krts.ui 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,3 +1,152 @@
1
- # Temporary Holding Version
1
+ # krts.ui
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ An accessible React UI library built on [React Aria Components](https://react-spectrum.adobe.com/react-aria/) and [Tailwind CSS v4](https://tailwindcss.com).
4
+
5
+ ```bash
6
+ npm i krts.ui
7
+ ```
8
+
9
+ Run the docs/playground locally with `npm run dev`.
10
+
11
+ ---
12
+
13
+ ## Setup
14
+
15
+ ### With Tailwind v4 (recommended)
16
+
17
+ ```css
18
+ /* app.css */
19
+ @import "tailwindcss";
20
+ @import "krts.ui/tailwind.css"; /* theme tokens + scans krts.ui's built classes */
21
+ ```
22
+
23
+ ### Without Tailwind
24
+
25
+ ```ts
26
+ import 'krts.ui/styles.css'; // precompiled
27
+ ```
28
+
29
+ ### Dark mode
30
+
31
+ Add `class="dark"` or `data-theme="dark"` to `<html>` (or to any subtree).
32
+
33
+ ### Theming
34
+
35
+ Every colour is a CSS variable:
36
+
37
+ ```css
38
+ :root {
39
+ --krts-primary: #3b2bff;
40
+ --krts-primary-hover: #4c3dff;
41
+ --krts-primary-pressed: #5b4dff;
42
+ --krts-primary-line: #2a1de0;
43
+ }
44
+ ```
45
+
46
+ ---
47
+
48
+ ## Usage
49
+
50
+ ```tsx
51
+ import { Button, HoldButton, Toaster, toast, WithTooltip } from 'krts.ui';
52
+
53
+ export function App() {
54
+ return (
55
+ <>
56
+ <Toaster />
57
+ <WithTooltip content="Saves to the cloud" shortcut="⌘S">
58
+ <Button variant="primary" onPress={save}>Save</Button>
59
+ </WithTooltip>
60
+
61
+ <HoldButton onConfirm={deleteProject}>Delete project</HoldButton>
62
+ </>
63
+ );
64
+ }
65
+ ```
66
+
67
+ ## Animation options
68
+
69
+ ### Menus, selects and popovers
70
+
71
+ ```tsx
72
+ <Select animation="scale" …/> // grows out of its trigger
73
+ <DropdownButton animation="none" …/> // instant
74
+ <Menu animation="fade" …/> // default: a quick 120ms fade
75
+
76
+ // Set the default for the whole app (a prop on a component still wins)
77
+ <KrtsProvider menuAnimation="scale">
78
+ <App />
79
+ </KrtsProvider>
80
+ ```
81
+
82
+ ## Gesture events
83
+
84
+ The gesture props work on `Button`, `GestureArea`, and anything that uses `useGesture`.
85
+
86
+ | Prop | Fires when | Notes |
87
+ | --- | --- | --- |
88
+ | `onSingleTap(e)` | A tap that is *not* part of a double or multi tap | Fires immediately if no double tap is possible; otherwise waits `multiTapDelay` (250ms) |
89
+ | `onDoubleTap(e)` | Two taps within `multiTapDelay` | |
90
+ | `onMultiTap(e)` | The end of every tap sequence | `e.count` is 1, 2, 3, … up to `maxTaps` (default 3) |
91
+ | `onHoldStart(e)` | Press begins | |
92
+ | `onHold(e)` | Held for `holdDuration` (default 500ms) | A hold never also counts as a tap |
93
+ | `onHoldTick(e)` | Every `holdTickInterval` (default 1000ms) while held | `e.seconds` is 1, 2, 3, … |
94
+ | `onHoldProgress(p)` | Every frame while held | `p` goes from 0 to 1 |
95
+ | `onHoldEnd(e)` | Released after `onHold` fired | `e.duration` is in ms |
96
+ | `onHoldCancel(e)` | Released, or the pointer moved away, before `holdDuration` | Includes ordinary taps |
97
+ | `onSwipe(e)` | Flick or drag | `e.direction` is `left`, `right`, `up` or `down`. A quick flick (> 0.11 px/ms) counts even if it's short |
98
+
99
+ ```tsx
100
+ <Button
101
+ onSingleTap={select}
102
+ onDoubleTap={open}
103
+ onHold={showContextMenu}
104
+ holdDuration={600}
105
+ >
106
+ photo.jpg
107
+ </Button>
108
+
109
+ // Hold for 3 seconds, counting up
110
+ <Button holdDuration={3000} onHoldTick={(e) => setSeconds(e.seconds)} onHold={launch}>
111
+ Hold to launch
112
+ </Button>
113
+
114
+ // Any element
115
+ const { gestureProps, isPressed } = useGesture({ onDoubleTap: like });
116
+ <div {...gestureProps} role="button" tabIndex={0} />
117
+
118
+ // Outside React
119
+ el.addEventListener('krts:doubletap', (e) => console.log(e.detail.count));
120
+ ```
121
+
122
+ ## Components
123
+
124
+ | Category | Components |
125
+ | --- | --- |
126
+ | Actions | `Button`, `HoldButton`, `CopyButton`, `ToggleButton`, `DropdownButton`, `SplitButton`, `GestureArea` |
127
+ | Menus & overlays | `Menu`, `MenuItem`, `MenuSection`, `MenuSeparator`, `SubmenuTrigger`, `Popover`, `Tooltip`, `TooltipTrigger`, `WithTooltip`, `Dialog`, `AlertDialog`, `Modal`, `Drawer` (left, right, bottom) |
128
+ | Forms | `TextField`, `TextAreaField`, `SearchField`, `NumberField`, `Select`, `Checkbox`, `CheckboxGroup`, `RadioGroup`, `Radio`, `Switch`, `Slider` (single or range) |
129
+ | Navigation | `Tabs` (pill and underline styles), `SegmentedControl`, `Link`, `Accordion`, `Disclosure` |
130
+ | Feedback | `Toaster` + `toast()`, `ProgressBar`, `Meter`, `Spinner`, `Skeleton` |
131
+ | Display | `Badge`, `Avatar`, `Kbd`, `Card`, `Separator` |
132
+ | Hooks | `useGesture`, `useGestureHandlers`, `useAnimatedWidth`, `useSmoothPending`, `usePerceivedProgress`, `usePrefersReducedMotion` |
133
+ | Config | `KrtsProvider` (`menuAnimation`), `useKrtsConfig` |
134
+
135
+ ### Toasts
136
+
137
+ ```ts
138
+ toast('Saved');
139
+ toast.success('Uploaded', { description: 'photo.jpg' });
140
+ toast('Conversation archived', { action: { label: 'Undo', onPress: restore } });
141
+ toast.promise(deploy(), { loading: 'Deploying…', success: 'Live', error: 'Failed' });
142
+ ```
143
+
144
+ ## Development
145
+
146
+ ```bash
147
+ npm run dev # docs / playground
148
+ npm test # vitest
149
+ npm run typecheck
150
+ npm run build # dist/ (ESM + CJS + d.ts + krts.css)
151
+ npm run build:docs # static docs site in docs/dist
152
+ ```