hiraki 0.0.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 ADDED
@@ -0,0 +1,177 @@
1
+ # hiraki (開き)
2
+
3
+ Zero-dependency React drawer component. All 4 directions, velocity-aware gestures, snap points, and 6 variants — without Radix, Framer Motion, or any external runtime dependency.
4
+
5
+ `~10 KB gzipped` — React >=18 is the only peer dep.
6
+
7
+ ---
8
+
9
+ ## Install
10
+
11
+ ```sh
12
+ npm install hiraki
13
+ pnpm add hiraki
14
+ yarn add hiraki
15
+ ```
16
+
17
+ ---
18
+
19
+ ## Usage
20
+
21
+ ```tsx
22
+ import { Drawer } from 'hiraki'
23
+
24
+ function App() {
25
+ return (
26
+ <Drawer.Root>
27
+ <Drawer.Trigger>Open</Drawer.Trigger>
28
+ <Drawer.Portal>
29
+ <Drawer.Overlay />
30
+ <Drawer.Content>
31
+ <Drawer.Handle />
32
+ <Drawer.Title>Title</Drawer.Title>
33
+ <Drawer.Description>Description</Drawer.Description>
34
+ <Drawer.Close>Close</Drawer.Close>
35
+ </Drawer.Content>
36
+ </Drawer.Portal>
37
+ </Drawer.Root>
38
+ )
39
+ }
40
+ ```
41
+
42
+ Controlled open state:
43
+
44
+ ```tsx
45
+ const [open, setOpen] = useState(false)
46
+
47
+ <Drawer.Root open={open} onOpenChange={setOpen}>
48
+ ...
49
+ </Drawer.Root>
50
+ ```
51
+
52
+ Snap points:
53
+
54
+ ```tsx
55
+ <Drawer.Root snapPoints={['25%', '55%', '90%']}>
56
+ ...
57
+ </Drawer.Root>
58
+ ```
59
+
60
+ Direction:
61
+
62
+ ```tsx
63
+ <Drawer.Root direction="right">
64
+ ...
65
+ </Drawer.Root>
66
+ ```
67
+
68
+ ---
69
+
70
+ ## API
71
+
72
+ ### Drawer.Root
73
+
74
+ | prop | type | default |
75
+ |------|------|---------|
76
+ | `open` | `boolean` | — |
77
+ | `defaultOpen` | `boolean` | `false` |
78
+ | `onOpenChange` | `(open: boolean) => void` | — |
79
+ | `direction` | `"top" \| "bottom" \| "left" \| "right"` | `"bottom"` |
80
+ | `variant` | `"default" \| "floating" \| "sheet" \| "fullscreen" \| "nested" \| "stack"` | `"default"` |
81
+ | `modal` | `boolean` | `true` |
82
+ | `dismissible` | `boolean` | `true` |
83
+ | `snapPoints` | `(number \| string)[]` | `[]` |
84
+ | `activeSnapPoint` | `number` | — |
85
+ | `onSnapPointChange` | `(index: number) => void` | — |
86
+ | `closeThreshold` | `number` | `0.5` |
87
+ | `rubberBand` | `boolean` | `true` |
88
+ | `inertia` | `boolean` | `true` |
89
+ | `shouldScaleBackground` | `boolean` | `false` |
90
+ | `onDragStart` | `(data: GestureCallbackData) => void` | — |
91
+ | `onDrag` | `(data: GestureCallbackData) => void` | — |
92
+ | `onDragEnd` | `(data: GestureCallbackData) => void` | — |
93
+
94
+ ### Drawer.Handle
95
+
96
+ | prop | type | default |
97
+ |------|------|---------|
98
+ | `visible` | `boolean` | `true` |
99
+ | `handleOnly` | `boolean` | `false` |
100
+
101
+ ### Drawer.Trigger / Drawer.Close
102
+
103
+ | prop | type | default |
104
+ |------|------|---------|
105
+ | `asChild` | `boolean` | `false` |
106
+
107
+ All components forward standard HTML attributes (`className`, `style`, `data-*`, event handlers).
108
+
109
+ ---
110
+
111
+ ## Snap points
112
+
113
+ Snap points define positions where the drawer rests. Three formats are supported:
114
+
115
+ - **Pixels from edge** — `200` means 200px of the drawer is visible
116
+ - **Percentage of viewport** — `'55%'` means 55% of viewport height (or width for left/right)
117
+ - **Content height** — `'content'` snaps to the drawer's natural content height
118
+
119
+ The drawer starts at the largest snap point. Velocity on release determines whether to snap forward, backward, or close.
120
+
121
+ ```tsx
122
+ // percentage
123
+ <Drawer.Root snapPoints={['25%', '55%', '90%']}>
124
+
125
+ // pixels
126
+ <Drawer.Root snapPoints={[200, 400, 600]}>
127
+
128
+ // content height
129
+ <Drawer.Root snapPoints={['content']}>
130
+
131
+ // controlled
132
+ <Drawer.Root
133
+ snapPoints={['25%', '55%', '90%']}
134
+ activeSnapPoint={snap}
135
+ onSnapPointChange={setSnap}
136
+ >
137
+ ```
138
+
139
+ ---
140
+
141
+ ## Styling
142
+
143
+ Hiraki is headless. It renders unstyled HTML elements. Add your own classes:
144
+
145
+ ```tsx
146
+ <Drawer.Content className="bg-white rounded-t-2xl shadow-xl">
147
+ <Drawer.Handle className="bg-gray-300" />
148
+ <Drawer.Title className="text-lg font-semibold px-6 pt-6">
149
+ Title
150
+ </Drawer.Title>
151
+ </Drawer.Content>
152
+ ```
153
+
154
+ CSS custom properties exposed during drag:
155
+
156
+ | property | description |
157
+ |----------|-------------|
158
+ | `--hiraki-drag-progress` | `0` (closed) to `1` (open), updates on every frame |
159
+
160
+ Scale the page behind the drawer:
161
+
162
+ ```tsx
163
+ <Drawer.Root shouldScaleBackground>
164
+ ...
165
+ </Drawer.Root>
166
+
167
+ // Mark the element to scale
168
+ <div data-hiraki-background>
169
+ {/* page content */}
170
+ </div>
171
+ ```
172
+
173
+ ---
174
+
175
+ ## License
176
+
177
+ MIT