@1337exp/taoui 1.1.1 → 1.3.2
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.RU.md +492 -0
- package/README.md +214 -202
- package/dist/index.cjs +1872 -435
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +558 -212
- package/dist/index.mjs +1873 -436
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +459 -71
- package/package.json +1 -1
- package/src/styles/date-popup.css +178 -0
package/README.md
CHANGED
|
@@ -1,107 +1,117 @@
|
|
|
1
1
|
# Tao UI
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
поменял несколько CSS-переменных — поменялась тема всего набора компонентов.
|
|
3
|
+
**English** · [Русский](README.RU.md)
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
A Vue 3 component library for Nuxt/Vue apps, driven by design tokens:
|
|
6
|
+
change a handful of CSS variables and the whole kit follows.
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
## Components
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
- **
|
|
13
|
-
- **
|
|
14
|
-
- **
|
|
15
|
-
- **
|
|
16
|
-
- **
|
|
17
|
-
- **
|
|
18
|
-
- **
|
|
19
|
-
- **
|
|
20
|
-
- **
|
|
10
|
+
### Basics
|
|
11
|
+
|
|
12
|
+
- **TaoBlock** — container with padding and radius
|
|
13
|
+
- **TaoButton** — `primary` / `secondary` / `ghost` / `danger`, sizes and states
|
|
14
|
+
- **TaoCard** — card with cover / header / footer slots. `#cover` can be a photo or `TaoCarousel`
|
|
15
|
+
- **TaoCopy** — clipboard icon. After a click, a “Copied” tooltip; if the trigger is gone, the tooltip is too
|
|
16
|
+
- **TaoInput** — text field with v-model, validation, and `#prefix` / `#suffix` slots (icon or text inside the frame)
|
|
17
|
+
- **TaoInputGroup** — outer glue: `#before` | field | `#after` (protocol, unit, button)
|
|
18
|
+
- **TaoModal** — modal with animation and slots
|
|
19
|
+
- **TaoDrawer** — side panel (filters, settings). Esc, backdrop click, focus trap — same as the modal
|
|
20
|
+
- **TaoSpoiler** — disclosure. `v-model` and `aria-expanded`. Neighbours do not close each other
|
|
21
|
+
- **TaoSpoilerGroup** — accordion: `v-model` is the open panel key (`null` = all closed); spoilers take `name`
|
|
22
|
+
- **TaoTabs** — tabbed sections
|
|
23
|
+
- **TaoTooltip** — hover hint
|
|
24
|
+
- **TaoPopover** — click panel with any slot content, Esc and outside click. Not a tooltip, not an action menu
|
|
21
25
|
|
|
22
26
|
### Layout
|
|
23
27
|
|
|
24
|
-
- **TaoContainer** —
|
|
25
|
-
- **TaoFlex** —
|
|
26
|
-
- **TaoSpace** —
|
|
27
|
-
- **TaoDivider** —
|
|
28
|
-
- **
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
- **
|
|
34
|
-
- **
|
|
35
|
-
- **
|
|
36
|
-
- **
|
|
37
|
-
- **
|
|
38
|
-
- **
|
|
39
|
-
- **
|
|
40
|
-
- **
|
|
41
|
-
- **
|
|
42
|
-
- **
|
|
43
|
-
- **
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
- **
|
|
51
|
-
- **
|
|
52
|
-
- **
|
|
53
|
-
- **
|
|
54
|
-
- **
|
|
55
|
-
- **
|
|
56
|
-
- **
|
|
57
|
-
- **
|
|
58
|
-
- **
|
|
59
|
-
- **
|
|
60
|
-
- **
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
- **
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
28
|
+
- **TaoContainer** — max-width (wide / slim / ultra-slim) and centering
|
|
29
|
+
- **TaoFlex** — flexbox wrapper: justify / align / direction / wrap / gap
|
|
30
|
+
- **TaoSpace** — even gap between children
|
|
31
|
+
- **TaoDivider** — `line` (hairline), `text` (line with a label), `gap` (empty space, size: small / medium / large)
|
|
32
|
+
- **TaoFieldset** — grouped frame: `legend` sits on the top border, `align` is start / center / end
|
|
33
|
+
- **TaoAnimatedBorder** — rainbow border wrapper (decorative, not tied to the theme)
|
|
34
|
+
|
|
35
|
+
### Forms
|
|
36
|
+
|
|
37
|
+
- **TaoCheckbox** — checkbox with v-model, pre/post slots, and `indeterminate`
|
|
38
|
+
- **TaoSwitch** — boolean toggle (`role="switch"`)
|
|
39
|
+
- **TaoRadio** / **TaoRadioGroup** — exclusive choice among 2–5 options
|
|
40
|
+
- **TaoSelect** — dropdown with keyboard, same chrome as Input. Clear via “Clear” in the list or Delete
|
|
41
|
+
- **TaoCombobox** — Select with a field: type to filter, `allow-create` writes a custom value into `v-model`, `create` lets the parent append the list
|
|
42
|
+
- **TaoDate** — a single day: `YYYY-MM-DD`, no time, no timezone. Calendar popup like Select
|
|
43
|
+
- **TaoDateRange** — a period: `v-model` is `{ start, end }` or `null`. First click is start, second is end (they swap if end is earlier). An incomplete pick is not written to the model
|
|
44
|
+
- **TaoFormField** — shared label / hint / error for form controls
|
|
45
|
+
- **TaoInputNumber** — number with min/max/step and ± on the right. Empty value is `null`
|
|
46
|
+
- **TaoQuantity** — cart quantity: `− | field | +`, integers, stock; minus at the minimum can remove the row
|
|
47
|
+
- **TaoTextarea** — autosizing multiline. `maxlength` caps input, `count` shows “entered / max”
|
|
48
|
+
- **TaoPinCode** — N cells. By default a click clears the cell and everything to the right (`clear-on="focus"`); `clear-on="input"` replaces the digit only when typing. The last cell blurs and emits `complete`
|
|
49
|
+
- **TaoSlider** — mouse, touch, and arrows. Optional precise input on right-click
|
|
50
|
+
- **TaoFileDrop** — drop zone (drag & drop + click). File names listed under the zone, `v-model` is `File[]`. Clearing the whole batch is the parent’s job (`clear-request`)
|
|
51
|
+
|
|
52
|
+
### Data display
|
|
53
|
+
|
|
54
|
+
- **TaoTable** — simple table: columns, empty, loading, sort via `v-model:sort`. Not a datagrid.
|
|
55
|
+
- **TaoPagination** — pages with ellipsis. Clicking “…” jumps `jump` pages (5 by default)
|
|
56
|
+
- **TaoEmpty** — empty list, no results, no access
|
|
57
|
+
- **TaoStages** — stage list: `wait` / `work` / `ok` / `bad`. Not a linear stepper
|
|
58
|
+
- **TaoSkeleton** — loading placeholder (text / title / circle / rect)
|
|
59
|
+
- **TaoCounter** — flipping digits (not an input)
|
|
60
|
+
- **TaoCarousel** — strip: full slide with `autoplay`, card with `peek`, row with `per-view`. Arrows via `controls` or `#prev` / `#next`, dots via `dots`
|
|
61
|
+
- **TaoAvatar** — photo or initials, sizes `small` / `medium` / `large`. Status `dot` and `count`
|
|
62
|
+
- **TaoTag** — badge with tones (neutral, success, danger, warning, info)
|
|
63
|
+
- **TaoAlert** — inline page/form banner (success / error / warning / info)
|
|
64
|
+
- **TaoProgress** — static bar (`progress` in %). Percent centered on top, or `showPercentage="right"`; `#left` / `#right` slots are captions, then the percent sits in parentheses on the right. `false` hides it. Width is `minWidth` / `maxWidth`, not the value domain
|
|
65
|
+
- **TaoLoader** — four-dot spinner
|
|
66
|
+
- **TaoImage** — `<img>` wrapper: fade-in and placeholder. `lazy` turns on native `loading="lazy"`
|
|
67
|
+
- **TaoIcon** — icon-font wrapper (see Icons below)
|
|
68
|
+
|
|
69
|
+
### Navigation
|
|
70
|
+
|
|
71
|
+
- **TaoLink** — uses `<NuxtLink>` in Nuxt and a plain `<a>` elsewhere, with no extra setup
|
|
72
|
+
- **TaoBreadcrumb** — crumbs: the last item is the current page
|
|
73
|
+
- **TaoDropdownMenu** — dropdown that flips at the viewport edge
|
|
74
|
+
- **TaoScrollTop** — floating “back to top” with a ripple. Appears on reverse scroll after `boundary`
|
|
75
|
+
|
|
76
|
+
### Feedback
|
|
77
|
+
|
|
78
|
+
- **toast()** — fluent toasts: `toast().success().message('Saved')`
|
|
79
|
+
- **confirm()** — overlay question: the same fluent API plus `await`. Not a toast — it waits for an answer and does not dismiss itself.
|
|
80
|
+
- **TaoToastViewport** / **TaoConfirmHost** — hosts; if they are missing from the tree, the first call mounts them on `body`
|
|
81
|
+
|
|
82
|
+
## Conventions
|
|
83
|
+
|
|
84
|
+
Visual tones: `success` | `danger` | `warning` | `info` | `neutral`.
|
|
85
|
+
`error` on Alert, Tag, and `toast()` is an alias of `danger`. Button already uses `danger`.
|
|
86
|
+
Stages describe a process, not a tone: `wait` / `work` / `ok` / `bad` (`danger` is accepted as `bad`).
|
|
87
|
+
|
|
88
|
+
Control sizes: `small` | `medium` | `large`.
|
|
89
|
+
Avatar also accepts short `s` / `m` / `l`. Divider `gap` used to call the large size `big` — that is an alias of `large`.
|
|
90
|
+
Container lives on another axis: `wide` / `slim` / `ultra-slim`.
|
|
91
|
+
|
|
92
|
+
## Icons
|
|
93
|
+
|
|
94
|
+
`TaoIcon` does not ship its own set — it renders `icon-<name>`
|
|
95
|
+
for an external icon font (IcoMoon / Fontello and the like). Connect a font
|
|
96
|
+
with classes such as `.icon-arrow-up { ... }` in the host app.
|
|
97
|
+
|
|
98
|
+
## Install
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
npm install @1337exp/taoui
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
From a local folder:
|
|
95
105
|
|
|
96
106
|
```bash
|
|
97
107
|
npm install ../path-to-tao-ui
|
|
98
108
|
```
|
|
99
109
|
|
|
100
|
-
##
|
|
110
|
+
## Usage
|
|
101
111
|
|
|
102
|
-
###
|
|
112
|
+
### Nuxt 3
|
|
103
113
|
|
|
104
|
-
|
|
114
|
+
Create `plugins/tao-ui.ts`:
|
|
105
115
|
|
|
106
116
|
```typescript
|
|
107
117
|
import { defineNuxtPlugin } from '#app'
|
|
@@ -112,7 +122,7 @@ export default defineNuxtPlugin((nuxtApp) => {
|
|
|
112
122
|
})
|
|
113
123
|
```
|
|
114
124
|
|
|
115
|
-
|
|
125
|
+
Import styles in `app.vue` or a layout:
|
|
116
126
|
|
|
117
127
|
```vue
|
|
118
128
|
<script setup>
|
|
@@ -120,7 +130,7 @@ import '@1337exp/taoui/styles.css'
|
|
|
120
130
|
</script>
|
|
121
131
|
```
|
|
122
132
|
|
|
123
|
-
###
|
|
133
|
+
### Vue 3
|
|
124
134
|
|
|
125
135
|
```javascript
|
|
126
136
|
// main.js
|
|
@@ -134,7 +144,7 @@ app.use(TaoUI)
|
|
|
134
144
|
app.mount('#app')
|
|
135
145
|
```
|
|
136
146
|
|
|
137
|
-
###
|
|
147
|
+
### Individual components
|
|
138
148
|
|
|
139
149
|
```vue
|
|
140
150
|
<script setup>
|
|
@@ -143,41 +153,41 @@ import '@1337exp/taoui/styles.css'
|
|
|
143
153
|
</script>
|
|
144
154
|
|
|
145
155
|
<template>
|
|
146
|
-
<TaoButton variant="primary"
|
|
147
|
-
<TaoInput v-model="text" label="
|
|
148
|
-
<TaoModal v-model="isOpen" title="
|
|
149
|
-
|
|
156
|
+
<TaoButton variant="primary">Press me</TaoButton>
|
|
157
|
+
<TaoInput v-model="text" label="Your text" />
|
|
158
|
+
<TaoModal v-model="isOpen" title="Title">
|
|
159
|
+
Modal body
|
|
150
160
|
</TaoModal>
|
|
151
161
|
</template>
|
|
152
162
|
```
|
|
153
163
|
|
|
154
164
|
## Toast
|
|
155
165
|
|
|
156
|
-
|
|
166
|
+
The chain runs in the same tick; `setTimeout(0)` actually shows the toast.
|
|
157
167
|
|
|
158
168
|
```javascript
|
|
159
169
|
import { toast } from '@1337exp/taoui'
|
|
160
170
|
|
|
161
|
-
toast().success().message('
|
|
162
|
-
toast().error().title('
|
|
163
|
-
toast.success('
|
|
164
|
-
toast.warning('
|
|
171
|
+
toast().success().message('Saved')
|
|
172
|
+
toast().error().title('Network').timeout(5000).message('No connection')
|
|
173
|
+
toast.success('Saved')
|
|
174
|
+
toast.warning('Draft', { timeout: 1000 })
|
|
165
175
|
```
|
|
166
176
|
|
|
167
|
-
|
|
177
|
+
Default position is `topCenter`. Globally:
|
|
168
178
|
|
|
169
179
|
```javascript
|
|
170
180
|
toast.defaults({ position: 'bottomRight' })
|
|
171
181
|
toast.byBottomRight()
|
|
172
182
|
```
|
|
173
183
|
|
|
174
|
-
`question`
|
|
184
|
+
There is no overlay `question` in this kit — that is confirm, not toast. Buttons on a toast, if needed:
|
|
175
185
|
|
|
176
186
|
```javascript
|
|
177
|
-
toast().info().message('
|
|
187
|
+
toast().info().message('Delete the file?').action('Delete', onRemove)
|
|
178
188
|
```
|
|
179
189
|
|
|
180
|
-
|
|
190
|
+
You can skip the viewport: the first call creates it. For explicit control (tests, a custom layout):
|
|
181
191
|
|
|
182
192
|
```vue
|
|
183
193
|
<TaoToastViewport />
|
|
@@ -185,60 +195,62 @@ Viewport можно не вставлять: первый вызов сам со
|
|
|
185
195
|
|
|
186
196
|
## Confirm
|
|
187
197
|
|
|
188
|
-
|
|
198
|
+
An overlay question in the center of the screen. This is not a toast: no progress bar, no auto-close, `await`, Esc and overlay click = cancel.
|
|
189
199
|
|
|
190
200
|
```javascript
|
|
191
201
|
import { confirm } from '@1337exp/taoui'
|
|
192
202
|
|
|
193
|
-
if (await confirm().title('
|
|
203
|
+
if (await confirm().title('Delete the file?').message('This cannot be undone').danger()) {
|
|
194
204
|
remove()
|
|
195
205
|
}
|
|
196
206
|
|
|
197
|
-
const ok = await confirm('
|
|
198
|
-
ok: '
|
|
199
|
-
cancel: '
|
|
207
|
+
const ok = await confirm('Leave without saving?', {
|
|
208
|
+
ok: 'Leave',
|
|
209
|
+
cancel: 'Stay',
|
|
200
210
|
})
|
|
201
211
|
```
|
|
202
212
|
|
|
203
|
-
|
|
213
|
+
Queue: a second `confirm()` while the first is open will wait. Default labels are “OK” / “Cancel”:
|
|
204
214
|
|
|
205
215
|
```javascript
|
|
206
216
|
confirm.defaults({ ok: 'Yes', cancel: 'No' })
|
|
207
217
|
```
|
|
208
218
|
|
|
209
|
-
##
|
|
219
|
+
## Forms
|
|
210
220
|
|
|
211
|
-
`TaoFormField`
|
|
221
|
+
`TaoFormField` attaches a shared label / hint / error and forwards `id` to the nested control.
|
|
212
222
|
|
|
213
223
|
```vue
|
|
214
|
-
<TaoFormField label="
|
|
224
|
+
<TaoFormField label="City" hint="Optional">
|
|
215
225
|
<TaoSelect v-model="city" :options="cities" />
|
|
216
226
|
</TaoFormField>
|
|
217
227
|
|
|
218
|
-
<TaoSwitch v-model="dark" label="
|
|
228
|
+
<TaoSwitch v-model="dark" label="Dark theme" />
|
|
219
229
|
|
|
220
|
-
<TaoRadioGroup v-model="plan" legend="
|
|
230
|
+
<TaoRadioGroup v-model="plan" legend="Plan">
|
|
221
231
|
<TaoRadio value="free" label="Free" />
|
|
222
232
|
<TaoRadio value="pro" label="Pro" />
|
|
223
233
|
</TaoRadioGroup>
|
|
224
234
|
|
|
225
|
-
<TaoAlert type="warning" title="
|
|
235
|
+
<TaoAlert type="warning" title="Draft">Save before you leave.</TaoAlert>
|
|
226
236
|
```
|
|
227
237
|
|
|
228
|
-
`TaoSelect`
|
|
238
|
+
`TaoSelect` opens from the keyboard (arrows, Enter, Esc); the list flips at the viewport edge. Delete or “Clear” at the bottom of the list resets the value to `null`.
|
|
239
|
+
|
|
240
|
+
`TaoCombobox` is the same menu with a field. Typing filters options. `allow-create` writes the typed string into `v-model` when there is no exact match. The list does not mutate itself: listen to `create` and append an option from the parent.
|
|
229
241
|
|
|
230
|
-
`TaoFormField`
|
|
242
|
+
`TaoFormField` also wraps `TaoTextarea` and `TaoCheckbox` — id, hint, and error are forwarded for you.
|
|
231
243
|
|
|
232
|
-
##
|
|
244
|
+
## Table and pagination
|
|
233
245
|
|
|
234
|
-
|
|
246
|
+
The table renders what you pass in: it does not slice or sort the data. That works for both server-side and client-side paging — the page is cut outside.
|
|
235
247
|
|
|
236
248
|
```vue
|
|
237
249
|
<TaoTable
|
|
238
250
|
:columns="columns"
|
|
239
251
|
:rows="pageRows"
|
|
240
252
|
v-model:sort="sort"
|
|
241
|
-
empty-text="
|
|
253
|
+
empty-text="No records yet"
|
|
242
254
|
>
|
|
243
255
|
<template #cell-status="{ row }">
|
|
244
256
|
<TaoTag :type="row.status === 'active' ? 'success' : 'neutral'">
|
|
@@ -252,21 +264,21 @@ confirm.defaults({ ok: 'Yes', cancel: 'No' })
|
|
|
252
264
|
|
|
253
265
|
```javascript
|
|
254
266
|
const columns = [
|
|
255
|
-
{ key: 'name', label: '
|
|
256
|
-
{ key: 'city', label: '
|
|
257
|
-
{ key: 'status', label: '
|
|
267
|
+
{ key: 'name', label: 'Name', sortable: true },
|
|
268
|
+
{ key: 'city', label: 'City' },
|
|
269
|
+
{ key: 'status', label: 'Status' },
|
|
258
270
|
]
|
|
259
271
|
```
|
|
260
272
|
|
|
261
|
-
|
|
273
|
+
The `cell-<key>` slot replaces a cell. `loading` shows an overlay; an empty list shows text or the `#empty` slot. Clicking a `sortable` header cycles `asc → desc → off`.
|
|
262
274
|
|
|
263
|
-
##
|
|
275
|
+
## Empty states and loading
|
|
264
276
|
|
|
265
277
|
```vue
|
|
266
|
-
<TaoEmpty title="
|
|
267
|
-
|
|
278
|
+
<TaoEmpty title="Nothing found">
|
|
279
|
+
Change the filter or reset search.
|
|
268
280
|
<template #action>
|
|
269
|
-
<TaoButton variant="secondary"
|
|
281
|
+
<TaoButton variant="secondary">Reset</TaoButton>
|
|
270
282
|
</template>
|
|
271
283
|
</TaoEmpty>
|
|
272
284
|
|
|
@@ -275,14 +287,14 @@ const columns = [
|
|
|
275
287
|
<TaoSkeleton variant="circle" />
|
|
276
288
|
|
|
277
289
|
<TaoStages :items="[
|
|
278
|
-
{ key: 'pay', label: '
|
|
279
|
-
{ key: 'pack', label: '
|
|
280
|
-
{ key: 'ship', label: '
|
|
290
|
+
{ key: 'pay', label: 'Payment', status: 'ok' },
|
|
291
|
+
{ key: 'pack', label: 'Packing', status: 'work' },
|
|
292
|
+
{ key: 'ship', label: 'Shipping', status: 'wait' },
|
|
281
293
|
]" />
|
|
282
294
|
```
|
|
283
295
|
|
|
284
296
|
```vue
|
|
285
|
-
<TaoInput v-model="q" placeholder="
|
|
297
|
+
<TaoInput v-model="q" placeholder="Search…">
|
|
286
298
|
<template #prefix>⌕</template>
|
|
287
299
|
</TaoInput>
|
|
288
300
|
|
|
@@ -290,7 +302,7 @@ const columns = [
|
|
|
290
302
|
<template #before>https://</template>
|
|
291
303
|
<TaoInput v-model="host" placeholder="example.com" />
|
|
292
304
|
<template #after>
|
|
293
|
-
<TaoButton
|
|
305
|
+
<TaoButton>Check</TaoButton>
|
|
294
306
|
</template>
|
|
295
307
|
</TaoInputGroup>
|
|
296
308
|
|
|
@@ -298,19 +310,23 @@ const columns = [
|
|
|
298
310
|
<TaoFormField label="Email">
|
|
299
311
|
<TaoInput v-model="email" type="email" />
|
|
300
312
|
</TaoFormField>
|
|
301
|
-
<TaoButton type="submit"
|
|
313
|
+
<TaoButton type="submit">Save</TaoButton>
|
|
302
314
|
</form>
|
|
303
315
|
|
|
304
|
-
<TaoFormField label="
|
|
316
|
+
<TaoFormField label="Quantity">
|
|
305
317
|
<TaoInputNumber v-model="qty" :min="1" :max="99" />
|
|
306
318
|
</TaoFormField>
|
|
307
319
|
|
|
308
320
|
<TaoQuantity v-model="qty" :max="12" @dec="onDec" />
|
|
309
321
|
|
|
310
|
-
<TaoFormField label="
|
|
322
|
+
<TaoFormField label="Delivery day" hint="The model is always YYYY-MM-DD">
|
|
311
323
|
<TaoDate v-model="day" min="2026-09-01" max="2026-09-30" />
|
|
312
324
|
</TaoFormField>
|
|
313
325
|
|
|
326
|
+
<TaoFormField label="Stay">
|
|
327
|
+
<TaoDateRange v-model="stay" min="2026-09-01" max="2026-09-30" />
|
|
328
|
+
</TaoFormField>
|
|
329
|
+
|
|
314
330
|
<TaoCounter :value="score" :max-digits="6" />
|
|
315
331
|
|
|
316
332
|
<TaoCarousel :autoplay="4000" loop dots>
|
|
@@ -323,49 +339,48 @@ const columns = [
|
|
|
323
339
|
<TaoCarousel v-model="slide" :per-view="5" :peek="28">
|
|
324
340
|
<template #prev></template>
|
|
325
341
|
<template #next="{ go, disabled }">
|
|
326
|
-
<button type="button" :disabled="disabled" @click="go"
|
|
342
|
+
<button type="button" :disabled="disabled" @click="go">next</button>
|
|
327
343
|
</template>
|
|
328
344
|
<article v-for="item in products" :key="item.id">…</article>
|
|
329
345
|
</TaoCarousel>
|
|
330
346
|
```
|
|
331
347
|
|
|
332
|
-
`TaoDrawer`
|
|
348
|
+
`TaoDrawer` is a side sheet, not a centered modal:
|
|
333
349
|
|
|
334
350
|
```vue
|
|
335
|
-
<TaoDrawer v-model="open" title="
|
|
351
|
+
<TaoDrawer v-model="open" title="Filters">
|
|
336
352
|
...
|
|
337
353
|
</TaoDrawer>
|
|
338
354
|
```
|
|
339
355
|
|
|
340
|
-
##
|
|
356
|
+
## Design tokens and theming
|
|
341
357
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
внешний вид всех компонентов сразу, без правок самих компонентов.
|
|
358
|
+
Library styles are three layers. Components **never** touch raw colors or sizes —
|
|
359
|
+
only semantic variables. That is the theming mechanism: override 20–30 variables
|
|
360
|
+
and every component follows, with no edits inside the components themselves.
|
|
346
361
|
|
|
347
362
|
```
|
|
348
|
-
primitives.css → semantic.css → themes/*.css (
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
363
|
+
primitives.css → semantic.css → themes/*.css (optional)
|
|
364
|
+
raw colors public theming ready-made themes on top
|
|
365
|
+
and scales, API: this is of semantic — light is
|
|
366
|
+
leave them alone what you change the example
|
|
352
367
|
```
|
|
353
368
|
|
|
354
|
-
###
|
|
369
|
+
### Layers
|
|
355
370
|
|
|
356
|
-
|
|
|
371
|
+
| File | Role | Touch it? |
|
|
357
372
|
|---|---|---|
|
|
358
|
-
| `primitives.css` |
|
|
359
|
-
| `semantic.css` |
|
|
360
|
-
| `themes/light.css` |
|
|
361
|
-
| `base.css` |
|
|
373
|
+
| `primitives.css` | Raw palette, space / radius / shadow scales (`--tao-orange-400`, `--tao-space-3`…) | Usually no |
|
|
374
|
+
| `semantic.css` | Default (dark) theme tokens: `--tao-color-accent`, `--tao-color-surface`, `--tao-color-danger`, etc. | **Yes — this is the theming API** |
|
|
375
|
+
| `themes/light.css` | Alternate theme via `[data-tao-theme="light"]` | Yes, as a sample |
|
|
376
|
+
| `base.css` | Global reset (scrollbar, links, box-sizing) | Rarely |
|
|
362
377
|
|
|
363
|
-
|
|
378
|
+
All four come in through `@1337exp/taoui/styles.css`.
|
|
364
379
|
|
|
365
|
-
###
|
|
380
|
+
### Your own theme
|
|
366
381
|
|
|
367
|
-
|
|
368
|
-
|
|
382
|
+
A theme is just semantic tokens under your selector.
|
|
383
|
+
Nothing in the components needs to change:
|
|
369
384
|
|
|
370
385
|
```css
|
|
371
386
|
/* my-brand-theme.css */
|
|
@@ -377,7 +392,7 @@ primitives.css → semantic.css → themes/*.css (опционально
|
|
|
377
392
|
--tao-color-surface-raised: #1a1a2e;
|
|
378
393
|
--tao-color-text: #d6d6e8;
|
|
379
394
|
--tao-color-text-strong: #ffffff;
|
|
380
|
-
/*
|
|
395
|
+
/* remaining tokens: see semantic.css */
|
|
381
396
|
}
|
|
382
397
|
```
|
|
383
398
|
|
|
@@ -390,40 +405,39 @@ primitives.css → semantic.css → themes/*.css (опционально
|
|
|
390
405
|
</template>
|
|
391
406
|
```
|
|
392
407
|
|
|
393
|
-
|
|
394
|
-
которые телепортируются в `body`:
|
|
408
|
+
Or switch the theme on `<html>` so modals/tooltips teleported to `body` pick it up:
|
|
395
409
|
|
|
396
410
|
```javascript
|
|
397
411
|
document.documentElement.setAttribute('data-tao-theme', 'light')
|
|
398
412
|
```
|
|
399
413
|
|
|
400
|
-
###
|
|
414
|
+
### Token groups
|
|
401
415
|
|
|
402
|
-
- `--tao-color-accent*` —
|
|
403
|
-
- `--tao-color-on-accent` —
|
|
404
|
-
- `--tao-color-selection`, `--tao-color-selection-text` —
|
|
405
|
-
- `--tao-color-surface*` —
|
|
406
|
-
- `--tao-color-border*` —
|
|
407
|
-
- `--tao-color-text*` —
|
|
408
|
-
- `--tao-color-danger*`, `--tao-color-success*`, `--tao-color-warning*`, `--tao-color-info*` —
|
|
409
|
-
- `--tao-color-input-*` —
|
|
410
|
-
- `--tao-radius-control`, `--tao-radius-panel` —
|
|
411
|
-
- `--tao-shadow-panel`, `--tao-shadow-overlay` —
|
|
416
|
+
- `--tao-color-accent*` — brand/accent (primary buttons, active tabs, links)
|
|
417
|
+
- `--tao-color-on-accent` — text on the accent (`--tao-color-text-on-accent` is an alias)
|
|
418
|
+
- `--tao-color-selection`, `--tao-color-selection-text` — text selection (`::selection`)
|
|
419
|
+
- `--tao-color-surface*` — container backgrounds (default / raised / sunken / hover)
|
|
420
|
+
- `--tao-color-border*` — borders
|
|
421
|
+
- `--tao-color-text*` — text (default / strong / muted / disabled)
|
|
422
|
+
- `--tao-color-danger*`, `--tao-color-success*`, `--tao-color-warning*`, `--tao-color-info*` — status colors
|
|
423
|
+
- `--tao-color-input-*` — fields, because input bg/text often differs from surface/text
|
|
424
|
+
- `--tao-radius-control`, `--tao-radius-panel` — radii (small controls vs large panels)
|
|
425
|
+
- `--tao-shadow-panel`, `--tao-shadow-overlay` — shadows
|
|
412
426
|
|
|
413
|
-
|
|
414
|
-
|
|
427
|
+
The full list lives in `src/styles/semantic.css` — the only file worth opening
|
|
428
|
+
to see the whole theming API.
|
|
415
429
|
|
|
416
|
-
###
|
|
430
|
+
### A theme from scratch, without primitives
|
|
417
431
|
|
|
418
432
|
```javascript
|
|
419
|
-
import '@1337exp/taoui/styles/primitives.css' //
|
|
420
|
-
import './my-semantic.css' //
|
|
433
|
+
import '@1337exp/taoui/styles/primitives.css' // keep the scales if you want
|
|
434
|
+
import './my-semantic.css' // your semantic layer instead of @1337exp/taoui/styles/semantic.css
|
|
421
435
|
import '@1337exp/taoui/styles/base.css'
|
|
422
436
|
```
|
|
423
437
|
|
|
424
|
-
##
|
|
438
|
+
## Showcase
|
|
425
439
|
|
|
426
|
-
|
|
440
|
+
To browse every component:
|
|
427
441
|
|
|
428
442
|
```bash
|
|
429
443
|
cd showcase
|
|
@@ -431,45 +445,43 @@ npm install
|
|
|
431
445
|
npm run dev
|
|
432
446
|
```
|
|
433
447
|
|
|
434
|
-
|
|
435
|
-
|
|
448
|
+
The showcase has a dark / light switch in the header, so you can see token
|
|
449
|
+
overrides without editing component code.
|
|
436
450
|
|
|
437
|
-
|
|
438
|
-
`npm run build`.
|
|
439
|
-
|
|
451
|
+
The showcase points at `src/` directly, so component edits show up without
|
|
452
|
+
`npm run build`. Building `dist/` is for publishing and for other projects
|
|
453
|
+
that install the package.
|
|
440
454
|
|
|
441
|
-
##
|
|
455
|
+
## Development
|
|
442
456
|
|
|
443
457
|
```bash
|
|
444
|
-
#
|
|
458
|
+
# Build the library
|
|
445
459
|
npm run build
|
|
446
460
|
|
|
447
|
-
#
|
|
461
|
+
# Watch mode
|
|
448
462
|
npm run dev
|
|
449
463
|
|
|
450
|
-
#
|
|
464
|
+
# Type check
|
|
451
465
|
npm run type-check
|
|
452
466
|
```
|
|
453
467
|
|
|
454
|
-
##
|
|
468
|
+
## Publishing to npm
|
|
455
469
|
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
репозитории; чтобы их получить, репозиторий клонируют.
|
|
470
|
+
Only `dist/` (the built library) and `src/styles/` (raw tokens, so you can
|
|
471
|
+
import `primitives.css` on its own for a custom theme) are published.
|
|
472
|
+
Component sources (`src/components/*.vue`), build configs, and `showcase/`
|
|
473
|
+
stay in the repo — clone it to get them.
|
|
461
474
|
|
|
462
|
-
`npm publish`
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
`npm publish` не нужно.
|
|
475
|
+
`npm publish` **itself** runs the type check and a full rebuild first
|
|
476
|
+
(`prepublishOnly` in `package.json`), so a stale or missing `dist/` cannot
|
|
477
|
+
reach the registry. You do not need to build by hand before `npm publish`.
|
|
466
478
|
|
|
467
|
-
|
|
479
|
+
See what would go into the tarball, without publishing:
|
|
468
480
|
|
|
469
481
|
```bash
|
|
470
482
|
npm pack --dry-run
|
|
471
483
|
```
|
|
472
484
|
|
|
473
|
-
##
|
|
485
|
+
## License
|
|
474
486
|
|
|
475
487
|
MIT
|