@exegia/specular 0.3.4 → 0.4.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 +81 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
# @exegia/specular
|
|
6
6
|
|
|
7
|
-
Pointer-following rim highlights and inset bezel utilities for Tailwind v4 + React.
|
|
7
|
+
Pointer-following rim highlights and inset bezel utilities for Tailwind v4 + React, with native ports for GPUI and SwiftUI.
|
|
8
8
|
|
|
9
9
|
[npm](https://www.npmjs.com/package/@exegia/specular) · [live examples](https://emmanuel-defreitas.github.io/specular/) · [MIT](LICENSE)
|
|
10
10
|
|
|
@@ -14,6 +14,12 @@ Pointer-following rim highlights and inset bezel utilities for Tailwind v4 + Rea
|
|
|
14
14
|
|
|
15
15
|
<sub>Six discs, one window listener. Explore the interactive presentation on the <a href="https://emmanuel-defreitas.github.io/specular/">example site</a>.</sub>
|
|
16
16
|
|
|
17
|
+
<a href="examples/video/specular-pointer-reel/renders/specular-pointer-reel.mp4">
|
|
18
|
+
<img src="examples/video/specular-pointer-reel/snapshots/frame-01-at-4.3s.png" alt="Light that follows you: a disc's inset light turning toward the pointer" width="240">
|
|
19
|
+
</a>
|
|
20
|
+
|
|
21
|
+
<sub>▶ <a href="examples/video/specular-pointer-reel/renders/specular-pointer-reel.mp4">Watch the 15-second reel</a>, a vertical cut made with <a href="https://github.com/heygen-com/hyperframes">HyperFrames</a>. Its source is in <a href="examples/video/specular-pointer-reel">examples/video</a>.</sub>
|
|
22
|
+
|
|
17
23
|
</div>
|
|
18
24
|
|
|
19
25
|
---
|
|
@@ -149,6 +155,79 @@ cargo run -p gpui-specular --example bezel
|
|
|
149
155
|
|
|
150
156
|
This crate currently supplies inset lighting and direction helpers. Image-overlay rims and image-tone sampling remain web-only.
|
|
151
157
|
|
|
158
|
+
## Native SwiftUI
|
|
159
|
+
|
|
160
|
+
The `Specular` Swift package brings the same lit and dim layers to SwiftUI, turning to follow the pointer. It draws with SwiftUI only: no web view, no global event monitor. Requires macOS 14, iOS 17 or visionOS 1, and Swift 6.
|
|
161
|
+
|
|
162
|
+
### 1. Add the Swift package
|
|
163
|
+
|
|
164
|
+
In Xcode, choose **File › Add Package Dependencies…**, paste `https://github.com/emmanuel-defreitas/specular.git`, and add the `Specular` library to your app target. In a `Package.swift`:
|
|
165
|
+
|
|
166
|
+
```swift
|
|
167
|
+
dependencies: [
|
|
168
|
+
.package(url: "https://github.com/emmanuel-defreitas/specular.git", from: "0.4.0"),
|
|
169
|
+
],
|
|
170
|
+
targets: [
|
|
171
|
+
.target(name: "App", dependencies: [.product(name: "Specular", package: "specular")]),
|
|
172
|
+
]
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
The manifest sits at the repository root and shares its version tags with the npm package.
|
|
176
|
+
|
|
177
|
+
### 2. Light a shape
|
|
178
|
+
|
|
179
|
+
`.specular` is a `Shape` modifier. It fills the shape and lights its edge:
|
|
180
|
+
|
|
181
|
+
```swift
|
|
182
|
+
import Specular
|
|
183
|
+
import SwiftUI
|
|
184
|
+
|
|
185
|
+
RoundedRectangle(cornerRadius: 32)
|
|
186
|
+
.specular(fill: Color(white: 0.25))
|
|
187
|
+
.frame(width: 160, height: 160)
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Without a surface, the light follows the color scheme: `.dark` in dark mode, `.light` otherwise. Pass one to choose: `.specular(.dark, fill: …)`. For any other view, borrow a shape the way `.background(_:in:)` does:
|
|
191
|
+
|
|
192
|
+
```swift
|
|
193
|
+
Label("Inbox", systemImage: "tray")
|
|
194
|
+
.padding()
|
|
195
|
+
.background(.quaternary, in: .capsule)
|
|
196
|
+
.specular(in: .capsule)
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### 3. Make the light follow the mouse
|
|
200
|
+
|
|
201
|
+
Every surface follows the pointer while the pointer is over it. To track the pointer anywhere in the window, add `.specularPointer()` to a container that fills the window. That's one hover handler for every surface inside, like the web package's single window listener. Each surface measures its own center, so surfaces anywhere in the layout work, including in scroll views:
|
|
202
|
+
|
|
203
|
+
```swift
|
|
204
|
+
struct ContentView: View {
|
|
205
|
+
var body: some View {
|
|
206
|
+
HStack(spacing: 32) {
|
|
207
|
+
ForEach(0..<4) { _ in
|
|
208
|
+
Circle().specular(fill: .gray).frame(width: 64, height: 64)
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
212
|
+
.specularPointer()
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
| `light:` | Behavior |
|
|
218
|
+
| --- | --- |
|
|
219
|
+
| `.pointer` (default) | Follows immediately, like the web and GPUI defaults. |
|
|
220
|
+
| `.pointer(animation: .specular)` | Eases each change with the web rim's 350 ms curve. |
|
|
221
|
+
| `.fixed(.degrees(90))` | A static light, clockwise from 12 o'clock. |
|
|
222
|
+
|
|
223
|
+
The light always takes the short way around, and stays lit from the top when Reduce Motion is on. On devices without a hovering pointer, `.specularPointer(touches: true)` also follows drags. Layer opacity is **0–1**, as in GPUI. Unlike CSS and GPUI inset shadows, the layers paint as an overlay above the view's content. To try the demo from this repository:
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
swift run SpecularDemo
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
See the [Swift package guide](swift/README.md) for custom layers and the direction helpers.
|
|
230
|
+
|
|
152
231
|
## Install
|
|
153
232
|
|
|
154
233
|
```bash
|
|
@@ -418,6 +497,7 @@ The React entry point also exports `PointerLightOptions`, `RimProps`, `ToneAlpha
|
|
|
418
497
|
```bash
|
|
419
498
|
make ci
|
|
420
499
|
make example-dev
|
|
500
|
+
make swift-test # macOS
|
|
421
501
|
```
|
|
422
502
|
|
|
423
503
|
The [example site](examples/vite-react) is the complete visual reference.
|