@hanzo/ui 8.27.8 → 8.27.10
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 +2 -1
- package/dist/backends/gui/3d-card.cjs +100 -0
- package/dist/backends/gui/3d-card.d.ts +59 -0
- package/dist/backends/gui/3d-card.d.ts.map +1 -0
- package/dist/backends/gui/3d-card.js +92 -0
- package/dist/backends/gui/3d-card.js.map +1 -0
- package/dist/backends/gui/3d-marquee.cjs +225 -0
- package/dist/backends/gui/3d-marquee.d.ts +114 -0
- package/dist/backends/gui/3d-marquee.d.ts.map +1 -0
- package/dist/backends/gui/3d-marquee.js +190 -0
- package/dist/backends/gui/3d-marquee.js.map +1 -0
- package/dist/backends/gui/3d-pin.cjs +51 -0
- package/dist/backends/gui/3d-pin.d.ts +14 -0
- package/dist/backends/gui/3d-pin.d.ts.map +1 -0
- package/dist/backends/gui/3d-pin.js +49 -0
- package/dist/backends/gui/3d-pin.js.map +1 -0
- package/dist/backends/gui/advanced-chart.cjs +61 -0
- package/dist/backends/gui/advanced-chart.d.ts +38 -0
- package/dist/backends/gui/advanced-chart.d.ts.map +1 -0
- package/dist/backends/gui/advanced-chart.js +59 -0
- package/dist/backends/gui/advanced-chart.js.map +1 -0
- package/dist/backends/gui/alert.cjs +106 -0
- package/dist/backends/gui/alert.d.ts +39 -0
- package/dist/backends/gui/alert.d.ts.map +1 -0
- package/dist/backends/gui/alert.js +102 -0
- package/dist/backends/gui/alert.js.map +1 -0
- package/dist/backends/gui/android.cjs +52 -0
- package/dist/backends/gui/android.d.ts +16 -0
- package/dist/backends/gui/android.d.ts.map +1 -0
- package/dist/backends/gui/android.js +50 -0
- package/dist/backends/gui/android.js.map +1 -0
- package/dist/backends/gui/animated-beam.cjs +97 -0
- package/dist/backends/gui/animated-beam.d.ts +57 -0
- package/dist/backends/gui/animated-beam.d.ts.map +1 -0
- package/dist/backends/gui/animated-beam.js +62 -0
- package/dist/backends/gui/animated-beam.js.map +1 -0
- package/dist/backends/gui/animated-cursor.cjs +183 -0
- package/dist/backends/gui/animated-cursor.d.ts +42 -0
- package/dist/backends/gui/animated-cursor.d.ts.map +1 -0
- package/dist/backends/gui/animated-cursor.js +181 -0
- package/dist/backends/gui/animated-cursor.js.map +1 -0
- package/dist/backends/gui/animated-testimonials.cjs +109 -0
- package/dist/backends/gui/animated-testimonials.d.ts +23 -0
- package/dist/backends/gui/animated-testimonials.d.ts.map +1 -0
- package/dist/backends/gui/animated-testimonials.js +74 -0
- package/dist/backends/gui/animated-testimonials.js.map +1 -0
- package/dist/backends/gui/animated-tooltip.cjs +100 -0
- package/dist/backends/gui/animated-tooltip.d.ts +15 -0
- package/dist/backends/gui/animated-tooltip.d.ts.map +1 -0
- package/dist/backends/gui/animated-tooltip.js +65 -0
- package/dist/backends/gui/animated-tooltip.js.map +1 -0
- package/dist/backends/gui/announcement.cjs +54 -0
- package/dist/backends/gui/announcement.d.ts +26 -0
- package/dist/backends/gui/announcement.d.ts.map +1 -0
- package/dist/backends/gui/announcement.js +52 -0
- package/dist/backends/gui/announcement.js.map +1 -0
- package/dist/backends/gui/apple-cards-carousel.cjs +198 -0
- package/dist/backends/gui/apple-cards-carousel.d.ts +45 -0
- package/dist/backends/gui/apple-cards-carousel.d.ts.map +1 -0
- package/dist/backends/gui/apple-cards-carousel.js +162 -0
- package/dist/backends/gui/apple-cards-carousel.js.map +1 -0
- package/dist/backends/gui/apple-hello-effect.cjs +38 -0
- package/dist/backends/gui/apple-hello-effect.d.ts +9 -0
- package/dist/backends/gui/apple-hello-effect.d.ts.map +1 -0
- package/dist/backends/gui/apple-hello-effect.js +36 -0
- package/dist/backends/gui/apple-hello-effect.js.map +1 -0
- package/dist/backends/gui/banner.cjs +108 -0
- package/dist/backends/gui/banner.d.ts +33 -0
- package/dist/backends/gui/banner.d.ts.map +1 -0
- package/dist/backends/gui/banner.js +106 -0
- package/dist/backends/gui/banner.js.map +1 -0
- package/dist/backends/gui/calendar.cjs +152 -0
- package/dist/backends/gui/calendar.d.ts +41 -0
- package/dist/backends/gui/calendar.d.ts.map +1 -0
- package/dist/backends/gui/calendar.js +151 -0
- package/dist/backends/gui/calendar.js.map +1 -0
- package/dist/backends/gui/choicebox.cjs +50 -0
- package/dist/backends/gui/choicebox.d.ts +33 -0
- package/dist/backends/gui/choicebox.d.ts.map +1 -0
- package/dist/backends/gui/choicebox.js +49 -0
- package/dist/backends/gui/choicebox.js.map +1 -0
- package/dist/backends/gui/code-block.cjs +120 -0
- package/dist/backends/gui/code-block.d.ts +22 -0
- package/dist/backends/gui/code-block.d.ts.map +1 -0
- package/dist/backends/gui/code-block.js +118 -0
- package/dist/backends/gui/code-block.js.map +1 -0
- package/dist/backends/gui/code-editor.cjs +195 -0
- package/dist/backends/gui/code-editor.d.ts +43 -0
- package/dist/backends/gui/code-editor.d.ts.map +1 -0
- package/dist/backends/gui/code-editor.js +160 -0
- package/dist/backends/gui/code-editor.js.map +1 -0
- package/dist/backends/gui/code-tabs.cjs +21 -0
- package/dist/backends/gui/code-tabs.d.ts +22 -0
- package/dist/backends/gui/code-tabs.d.ts.map +1 -0
- package/dist/backends/gui/code-tabs.js +19 -0
- package/dist/backends/gui/code-tabs.js.map +1 -0
- package/dist/backends/gui/color-picker.cjs +141 -0
- package/dist/backends/gui/color-picker.d.ts +25 -0
- package/dist/backends/gui/color-picker.d.ts.map +1 -0
- package/dist/backends/gui/color-picker.js +139 -0
- package/dist/backends/gui/color-picker.js.map +1 -0
- package/dist/backends/gui/combobox.cjs +42 -0
- package/dist/backends/gui/combobox.d.ts +39 -0
- package/dist/backends/gui/combobox.d.ts.map +1 -0
- package/dist/backends/gui/combobox.js +40 -0
- package/dist/backends/gui/combobox.js.map +1 -0
- package/dist/backends/gui/company-profile.cjs +43 -0
- package/dist/backends/gui/company-profile.d.ts +33 -0
- package/dist/backends/gui/company-profile.d.ts.map +1 -0
- package/dist/backends/gui/company-profile.js +41 -0
- package/dist/backends/gui/company-profile.js.map +1 -0
- package/dist/backends/gui/comparison.cjs +43 -0
- package/dist/backends/gui/comparison.d.ts +16 -0
- package/dist/backends/gui/comparison.d.ts.map +1 -0
- package/dist/backends/gui/comparison.js +41 -0
- package/dist/backends/gui/comparison.js.map +1 -0
- package/dist/backends/gui/credit-card.cjs +80 -0
- package/dist/backends/gui/credit-card.d.ts +21 -0
- package/dist/backends/gui/credit-card.d.ts.map +1 -0
- package/dist/backends/gui/credit-card.js +78 -0
- package/dist/backends/gui/credit-card.js.map +1 -0
- package/dist/backends/gui/crypto-market.cjs +128 -0
- package/dist/backends/gui/crypto-market.d.ts +52 -0
- package/dist/backends/gui/crypto-market.d.ts.map +1 -0
- package/dist/backends/gui/crypto-market.js +126 -0
- package/dist/backends/gui/crypto-market.js.map +1 -0
- package/dist/backends/gui/crypto-screener.cjs +55 -0
- package/dist/backends/gui/crypto-screener.d.ts +42 -0
- package/dist/backends/gui/crypto-screener.d.ts.map +1 -0
- package/dist/backends/gui/crypto-screener.js +53 -0
- package/dist/backends/gui/crypto-screener.js.map +1 -0
- package/dist/backends/gui/cursor.cjs +40 -0
- package/dist/backends/gui/cursor.d.ts +16 -0
- package/dist/backends/gui/cursor.d.ts.map +1 -0
- package/dist/backends/gui/cursor.js +38 -0
- package/dist/backends/gui/cursor.js.map +1 -0
- package/dist/backends/gui/data-table.cjs +211 -0
- package/dist/backends/gui/data-table.d.ts +71 -0
- package/dist/backends/gui/data-table.d.ts.map +1 -0
- package/dist/backends/gui/data-table.js +175 -0
- package/dist/backends/gui/data-table.js.map +1 -0
- package/dist/backends/gui/date-picker.cjs +66 -0
- package/dist/backends/gui/date-picker.d.ts +29 -0
- package/dist/backends/gui/date-picker.d.ts.map +1 -0
- package/dist/backends/gui/date-picker.js +64 -0
- package/dist/backends/gui/date-picker.js.map +1 -0
- package/dist/backends/gui/desktop-spotlight.cjs +46 -0
- package/dist/backends/gui/desktop-spotlight.d.ts +34 -0
- package/dist/backends/gui/desktop-spotlight.d.ts.map +1 -0
- package/dist/backends/gui/desktop-spotlight.js +44 -0
- package/dist/backends/gui/desktop-spotlight.js.map +1 -0
- package/dist/backends/gui/desktop-window.cjs +180 -0
- package/dist/backends/gui/desktop-window.d.ts +51 -0
- package/dist/backends/gui/desktop-window.d.ts.map +1 -0
- package/dist/backends/gui/desktop-window.js +177 -0
- package/dist/backends/gui/desktop-window.js.map +1 -0
- package/dist/backends/gui/desktop.cjs +238 -0
- package/dist/backends/gui/desktop.d.ts +109 -0
- package/dist/backends/gui/desktop.d.ts.map +1 -0
- package/dist/backends/gui/desktop.js +199 -0
- package/dist/backends/gui/desktop.js.map +1 -0
- package/dist/backends/gui/dialog-stack.cjs +26 -0
- package/dist/backends/gui/dialog-stack.d.ts +23 -0
- package/dist/backends/gui/dialog-stack.d.ts.map +1 -0
- package/dist/backends/gui/dialog-stack.js +24 -0
- package/dist/backends/gui/dialog-stack.js.map +1 -0
- package/dist/backends/gui/dock.cjs +99 -0
- package/dist/backends/gui/dock.d.ts +41 -0
- package/dist/backends/gui/dock.d.ts.map +1 -0
- package/dist/backends/gui/dock.js +96 -0
- package/dist/backends/gui/dock.js.map +1 -0
- package/dist/backends/gui/dropzone.cjs +142 -0
- package/dist/backends/gui/dropzone.d.ts +12 -0
- package/dist/backends/gui/dropzone.d.ts.map +1 -0
- package/dist/backends/gui/dropzone.js +140 -0
- package/dist/backends/gui/dropzone.js.map +1 -0
- package/dist/backends/gui/editor.cjs +80 -0
- package/dist/backends/gui/editor.d.ts +23 -0
- package/dist/backends/gui/editor.d.ts.map +1 -0
- package/dist/backends/gui/editor.js +45 -0
- package/dist/backends/gui/editor.js.map +1 -0
- package/dist/backends/gui/empty.cjs +71 -0
- package/dist/backends/gui/empty.d.ts +43 -0
- package/dist/backends/gui/empty.d.ts.map +1 -0
- package/dist/backends/gui/empty.js +63 -0
- package/dist/backends/gui/empty.js.map +1 -0
- package/dist/backends/gui/financials.cjs +45 -0
- package/dist/backends/gui/financials.d.ts +36 -0
- package/dist/backends/gui/financials.d.ts.map +1 -0
- package/dist/backends/gui/financials.js +43 -0
- package/dist/backends/gui/financials.js.map +1 -0
- package/dist/backends/gui/forex-market.cjs +21 -0
- package/dist/backends/gui/forex-market.d.ts +17 -0
- package/dist/backends/gui/forex-market.d.ts.map +1 -0
- package/dist/backends/gui/forex-market.js +19 -0
- package/dist/backends/gui/forex-market.js.map +1 -0
- package/dist/backends/gui/forex-screener.cjs +57 -0
- package/dist/backends/gui/forex-screener.d.ts +45 -0
- package/dist/backends/gui/forex-screener.d.ts.map +1 -0
- package/dist/backends/gui/forex-screener.js +55 -0
- package/dist/backends/gui/forex-screener.js.map +1 -0
- package/dist/backends/gui/gantt.cjs +50 -0
- package/dist/backends/gui/gantt.d.ts +19 -0
- package/dist/backends/gui/gantt.d.ts.map +1 -0
- package/dist/backends/gui/gantt.js +49 -0
- package/dist/backends/gui/gantt.js.map +1 -0
- package/dist/backends/gui/index.cjs +108 -1
- package/dist/backends/gui/index.d.ts +41 -0
- package/dist/backends/gui/index.d.ts.map +1 -1
- package/dist/backends/gui/index.js +41 -0
- package/dist/backends/gui/index.js.map +1 -1
- package/dist/canvas.cjs +3 -3
- package/dist/canvas.js +3 -3
- package/dist/canvas.js.map +1 -1
- package/dist/gallery.html +2 -2
- package/dist/grid.cjs +19 -43
- package/dist/grid.d.ts +36 -1
- package/dist/grid.d.ts.map +1 -1
- package/dist/grid.js +19 -43
- package/dist/grid.js.map +1 -1
- package/dist/index.cjs +70 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/index.node.cjs +70 -1
- package/dist/index.node.js +3 -0
- package/dist/product/ChunkGuard.cjs +58 -0
- package/dist/product/ChunkGuard.d.ts +7 -0
- package/dist/product/ChunkGuard.d.ts.map +1 -0
- package/dist/product/ChunkGuard.js +56 -0
- package/dist/product/ChunkGuard.js.map +1 -0
- package/dist/product/DetailPane.cjs +46 -0
- package/dist/product/DetailPane.d.ts +47 -0
- package/dist/product/DetailPane.d.ts.map +1 -0
- package/dist/product/DetailPane.js +43 -0
- package/dist/product/DetailPane.js.map +1 -0
- package/dist/product/Fact.cjs +19 -0
- package/dist/product/Fact.d.ts +23 -0
- package/dist/product/Fact.d.ts.map +1 -0
- package/dist/product/Fact.js +17 -0
- package/dist/product/Fact.js.map +1 -0
- package/dist/product/chunkGuard.logic.cjs +54 -0
- package/dist/product/chunkGuard.logic.d.ts +26 -0
- package/dist/product/chunkGuard.logic.d.ts.map +1 -0
- package/dist/product/chunkGuard.logic.js +49 -0
- package/dist/product/chunkGuard.logic.js.map +1 -0
- package/dist/product/index.cjs +10 -0
- package/dist/product/index.d.ts +3 -0
- package/dist/product/index.d.ts.map +1 -1
- package/dist/product/index.js +10 -0
- package/dist/product/index.js.map +1 -1
- package/package.json +5 -3
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* AppleCardsCarousel — a stack of full-bleed cards with one in front and the
|
|
5
|
+
* next two peeking out behind it, each a step smaller and further to the side,
|
|
6
|
+
* the way App Store "Today" cards fan out.
|
|
7
|
+
*
|
|
8
|
+
* A pointer drag on the front card carries it sideways and slides its
|
|
9
|
+
* background image the other way for depth; releasing past `swipeThreshold`,
|
|
10
|
+
* or with a quick flick, commits to the neighbour and the stack springs into
|
|
11
|
+
* its new order. A press that begins on a control inside the card belongs to
|
|
12
|
+
* the control, not to a drag. Arrow keys while the region has focus, the arrow
|
|
13
|
+
* buttons, the dots and an optional auto-play (held while the pointer is over
|
|
14
|
+
* the region, and never started under a reduced-motion preference) all move
|
|
15
|
+
* the same index. Cards more than two steps from the front are not drawn.
|
|
16
|
+
*
|
|
17
|
+
* Motion is CSS transform + transition on the card, switched off for the
|
|
18
|
+
* duration of a drag so the card tracks the pointer without lag, and off
|
|
19
|
+
* altogether under a reduced-motion preference.
|
|
20
|
+
*/
|
|
21
|
+
import * as React from 'react';
|
|
22
|
+
import { Image, SizableText, XStack, YStack } from '@hanzo/gui';
|
|
23
|
+
import { ChevronLeft, ChevronRight } from '@hanzogui/lucide-icons-2';
|
|
24
|
+
import { glass } from '../../glass.js';
|
|
25
|
+
import { sx } from '../../sx.js';
|
|
26
|
+
import { drag, dragPos, touch } from './gesture.js';
|
|
27
|
+
const SPRING = 'transform .4s cubic-bezier(.2,.8,.2,1), opacity .4s ease';
|
|
28
|
+
/** px/ms — a flick commits regardless of distance. */
|
|
29
|
+
const FLICK = 0.5;
|
|
30
|
+
/** Two pointer samples closer than half a frame say nothing about speed. */
|
|
31
|
+
const FRAME = 8;
|
|
32
|
+
/** A pointer that has been still this long before release is not flicking. */
|
|
33
|
+
const STALE = 100;
|
|
34
|
+
const ARROW = 36;
|
|
35
|
+
/** What a press inside a card must not turn into a drag. */
|
|
36
|
+
const CONTROL = 'a,button,input,select,textarea';
|
|
37
|
+
const WHITE = (a) => `rgba(255,255,255,${a})`;
|
|
38
|
+
/** Position, scale, opacity and stacking order for the card `offset` slots from the front. */
|
|
39
|
+
const layerAt = (offset, cardCount, stackOffset, stackScale) => {
|
|
40
|
+
const abs = Math.abs(offset);
|
|
41
|
+
if (abs > 2)
|
|
42
|
+
return { visible: false, x: 0, scale: 1, opacity: 0, zIndex: 0 };
|
|
43
|
+
return {
|
|
44
|
+
visible: true,
|
|
45
|
+
x: offset * stackOffset,
|
|
46
|
+
scale: Math.pow(stackScale, abs),
|
|
47
|
+
opacity: Math.max(0, 1 - abs * 0.3),
|
|
48
|
+
zIndex: cardCount - abs,
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
const still = () => typeof window !== 'undefined' && !!window.matchMedia?.('(prefers-reduced-motion: reduce)').matches;
|
|
52
|
+
export function AppleCardsCarousel({ cards, autoPlay = false, autoPlayInterval = 5000, className, cardClassName, showArrows = true, showDots = true, parallaxOffset = 50, stackOffset = 10, stackScale = 0.95, swipeThreshold = 50, }) {
|
|
53
|
+
const [index, setIndex] = React.useState(0);
|
|
54
|
+
const [hovering, setHovering] = React.useState(false);
|
|
55
|
+
const [dragX, setDragX] = React.useState(0);
|
|
56
|
+
const [dragging, setDragging] = React.useState(false);
|
|
57
|
+
/**
|
|
58
|
+
* The drag in flight — pointer origin, offset so far, and the sample its
|
|
59
|
+
* velocity is measured from — or null between drags. `pointermove` fires for
|
|
60
|
+
* a pointer that is merely passing over the card, so null is what keeps a
|
|
61
|
+
* hover from moving it.
|
|
62
|
+
*/
|
|
63
|
+
const track = React.useRef(null);
|
|
64
|
+
/** The reduced-motion preference, read once mounted so the server and the client agree. */
|
|
65
|
+
const [calm, setCalm] = React.useState(false);
|
|
66
|
+
React.useEffect(() => setCalm(still()), []);
|
|
67
|
+
const count = cards.length;
|
|
68
|
+
const step = React.useCallback((by) => setIndex((i) => (count ? (i + by + count) % count : 0)), [count]);
|
|
69
|
+
const goNext = React.useCallback(() => step(1), [step]);
|
|
70
|
+
const goPrevious = React.useCallback(() => step(-1), [step]);
|
|
71
|
+
React.useEffect(() => {
|
|
72
|
+
if (!autoPlay || hovering || count < 2 || calm)
|
|
73
|
+
return;
|
|
74
|
+
const t = setInterval(goNext, autoPlayInterval);
|
|
75
|
+
return () => clearInterval(t);
|
|
76
|
+
}, [autoPlay, hovering, autoPlayInterval, goNext, count, calm]);
|
|
77
|
+
const onKeyDown = React.useCallback((e) => {
|
|
78
|
+
if (e.key === 'ArrowLeft')
|
|
79
|
+
goPrevious();
|
|
80
|
+
else if (e.key === 'ArrowRight')
|
|
81
|
+
goNext();
|
|
82
|
+
}, [goNext, goPrevious]);
|
|
83
|
+
const begin = React.useCallback((e) => {
|
|
84
|
+
// The pointer capture `drag()` took would retarget the control's click to
|
|
85
|
+
// the card, so the capture goes back and the drag never arms.
|
|
86
|
+
const on = e.target;
|
|
87
|
+
if (on?.closest?.(CONTROL)) {
|
|
88
|
+
const card = e.currentTarget;
|
|
89
|
+
if (e.pointerId != null)
|
|
90
|
+
card?.releasePointerCapture?.(e.pointerId);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
track.current = { origin: dragPos(e, true), x: 0, v: 0, sample: { x: 0, t: Date.now() } };
|
|
94
|
+
setDragging(true);
|
|
95
|
+
}, []);
|
|
96
|
+
const move = React.useCallback((e) => {
|
|
97
|
+
const k = track.current;
|
|
98
|
+
if (!k)
|
|
99
|
+
return;
|
|
100
|
+
k.x = dragPos(e, true) - k.origin;
|
|
101
|
+
const t = Date.now();
|
|
102
|
+
const dt = t - k.sample.t;
|
|
103
|
+
if (dt >= FRAME) {
|
|
104
|
+
k.v = (k.x - k.sample.x) / dt;
|
|
105
|
+
k.sample = { x: k.x, t };
|
|
106
|
+
}
|
|
107
|
+
setDragX(k.x);
|
|
108
|
+
}, []);
|
|
109
|
+
const end = React.useCallback(() => {
|
|
110
|
+
const k = track.current;
|
|
111
|
+
if (!k)
|
|
112
|
+
return;
|
|
113
|
+
track.current = null;
|
|
114
|
+
const { x, v, sample } = k;
|
|
115
|
+
const flick = Date.now() - sample.t <= STALE && Math.abs(v) > FLICK;
|
|
116
|
+
if (Math.abs(x) > swipeThreshold || flick)
|
|
117
|
+
step(x > 0 ? -1 : 1);
|
|
118
|
+
setDragging(false);
|
|
119
|
+
setDragX(0);
|
|
120
|
+
}, [step, swipeThreshold]);
|
|
121
|
+
const gesture = drag({ begin, move, end, enabled: count > 1 });
|
|
122
|
+
const settle = dragging || calm ? 'none' : SPRING;
|
|
123
|
+
return (_jsxs(YStack, { "data-slot": "apple-carousel", role: "region", "aria-roledescription": "carousel", "aria-label": "Cards", position: "relative", width: "100%", maxW: 1152, mx: "auto", px: "$4", py: "$6", tabIndex: 0, onKeyDown: onKeyDown, onMouseEnter: () => setHovering(true), onMouseLeave: () => setHovering(false), ...sx(className), children: [_jsx(XStack, { position: "relative", width: "100%", height: 400, $md: { height: 500 }, $lg: { height: 600 }, items: "center", justify: "center", children: cards.map((card, i) => {
|
|
124
|
+
const layer = layerAt(i - index, count, stackOffset, stackScale);
|
|
125
|
+
const active = i === index;
|
|
126
|
+
const x = layer.x + (active ? dragX : 0);
|
|
127
|
+
const parallax = active
|
|
128
|
+
? Math.max(-parallaxOffset, Math.min(parallaxOffset, (-dragX / 200) * parallaxOffset))
|
|
129
|
+
: 0;
|
|
130
|
+
return (_jsx(YStack, { "data-slot": "apple-carousel-card", "data-active": active || undefined, role: "group", "aria-roledescription": "slide", "aria-label": `${i + 1} of ${count}`, "aria-hidden": !active || undefined, position: "absolute", inset: 0, pointerEvents: active ? 'auto' : 'none', display: layer.visible ? 'flex' : 'none', cursor: active ? (dragging ? 'grabbing' : 'grab') : undefined, style: {
|
|
131
|
+
transform: `translateX(${x}px) scale(${layer.scale})`,
|
|
132
|
+
opacity: layer.opacity,
|
|
133
|
+
zIndex: layer.zIndex,
|
|
134
|
+
transition: settle,
|
|
135
|
+
// A sideways swipe is the card's; the page keeps vertical
|
|
136
|
+
// scroll. Without this a touch browser takes the pan as a
|
|
137
|
+
// scroll and cancels the pointer before the threshold.
|
|
138
|
+
touchAction: 'pan-y',
|
|
139
|
+
userSelect: 'none',
|
|
140
|
+
}, ...(active ? gesture : null), children: _jsxs(YStack, { position: "relative", width: "100%", height: "100%", overflow: "hidden", rounded: "$6", borderWidth: 1, borderColor: "$borderColor", bg: "$panel", shadowColor: "rgba(0,0,0,0.25)", shadowOffset: { width: 0, height: 25 }, shadowRadius: 50, style: { background: card.gradient }, ...sx(cardClassName), children: [card.image ? (_jsxs(YStack, { position: "absolute", inset: 0, style: {
|
|
141
|
+
transform: `translateX(${parallax}px)`,
|
|
142
|
+
transition: dragging || calm ? 'none' : 'transform .2s ease',
|
|
143
|
+
}, children: [_jsx(Image, { src: card.image, alt: card.title, width: "100%", height: "100%", objectFit: "cover" }), _jsx(YStack, { position: "absolute", inset: 0, style: { background: 'linear-gradient(to top, rgba(0,0,0,.6), rgba(0,0,0,.2), transparent)' } })] })) : null, _jsx(YStack, { position: "relative", justify: "flex-end", height: "100%", p: "$6", $md: { p: '$8' }, gap: "$2", children: card.content ?? (_jsxs(_Fragment, { children: [_jsx(SizableText, { size: "$9", fontWeight: "700", color: "white", children: card.title }), card.subtitle ? (_jsx(SizableText, { size: "$6", color: WHITE(0.8), children: card.subtitle })) : null, card.description ? (_jsx(SizableText, { size: "$4", color: WHITE(0.7), maxW: 640, children: card.description })) : null] })) })] }) }, card.id));
|
|
144
|
+
}) }), showArrows
|
|
145
|
+
? [
|
|
146
|
+
['previous', 'Previous card', goPrevious, ChevronLeft, { left: 16 }],
|
|
147
|
+
['next', 'Next card', goNext, ChevronRight, { right: 16 }],
|
|
148
|
+
].map(([name, label, go, Chevron, side]) => (_jsx(XStack, { "data-slot": `apple-carousel-${name}`, render: _jsx("button", { type: "button" }), "aria-label": label, position: "absolute", display: "none", $md: { display: 'flex' }, style: { top: '50%', transform: 'translateY(-50%)', zIndex: 20, ...side }, items: "center", justify: "center", width: ARROW, height: ARROW, rounded: 999, ...glass(2), bg: WHITE(0.1), hoverStyle: { bg: WHITE(0.2) }, borderWidth: 1, borderColor: WHITE(0.2), cursor: "pointer", ...touch(ARROW, 44), onClick: go, children: _jsx(Chevron, { size: 20, color: "white" }) }, name)))
|
|
149
|
+
: null, showDots ? (_jsx(XStack, { position: "absolute", style: { bottom: 16, left: '50%', transform: 'translateX(-50%)', zIndex: 20 }, gap: "$2", children: cards.map((card, i) => (_jsx(XStack, { "data-slot": "apple-carousel-dot", render: _jsx("button", { type: "button" }), "aria-label": `Go to card ${i + 1}`, "aria-current": i === index || undefined, "data-active": i === index || undefined, height: 8, width: i === index ? 32 : 8, rounded: 999, bg: i === index ? 'white' : WHITE(0.4), hoverStyle: { bg: i === index ? 'white' : WHITE(0.6) }, cursor: "pointer", style: { transition: 'width .3s ease, background-color .3s ease' }, ...touch(8, 44, 'y'), onClick: () => setIndex(i) }, card.id))) })) : null] }));
|
|
150
|
+
}
|
|
151
|
+
/** Pre-built CSS gradients for cards that skip `image`. */
|
|
152
|
+
export const gradientPresets = {
|
|
153
|
+
sunset: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
|
|
154
|
+
ocean: 'linear-gradient(135deg, #667eea 0%, #4ca1af 100%)',
|
|
155
|
+
fire: 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)',
|
|
156
|
+
forest: 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)',
|
|
157
|
+
galaxy: 'linear-gradient(135deg, #7303c0 0%, #ec38bc 50%, #fdeff9 100%)',
|
|
158
|
+
aurora: 'linear-gradient(135deg, #89f7fe 0%, #66a6ff 100%)',
|
|
159
|
+
peach: 'linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%)',
|
|
160
|
+
lavender: 'linear-gradient(135deg, #a8edea 0%, #fed6e3 100%)',
|
|
161
|
+
};
|
|
162
|
+
//# sourceMappingURL=apple-cards-carousel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apple-cards-carousel.js","sourceRoot":"","sources":["../../../src/backends/gui/apple-cards-carousel.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use client';"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.AppleHelloEffect = AppleHelloEffect;
|
|
5
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
|
+
/**
|
|
7
|
+
* AppleHelloEffect — a string that reveals itself one letter at a time. Each
|
|
8
|
+
* letter fades in while rising fifty pixels into place, and the letters start
|
|
9
|
+
* a tenth of a second apart, the way Apple's "Hello" splash plays.
|
|
10
|
+
*
|
|
11
|
+
* `text` is the string and `duration` the seconds each letter's own rise
|
|
12
|
+
* takes; the stagger rides on each letter as `animationDelay`. The keyframe
|
|
13
|
+
* rides along as a hoisted `<style>` keyed by `href`, so any number of these
|
|
14
|
+
* on a page emit it once, and under `prefers-reduced-motion` the letters stand
|
|
15
|
+
* whole and still.
|
|
16
|
+
*/
|
|
17
|
+
const gui_1 = require("@hanzo/gui");
|
|
18
|
+
const slot_1 = require("./slot.cjs");
|
|
19
|
+
const KEYFRAMES = `
|
|
20
|
+
@keyframes hello-rise { from { opacity: 0; transform: translateY(50px) } to { opacity: 1; transform: none } }
|
|
21
|
+
[data-slot="apple-hello-effect-letter"] { animation-name: hello-rise; animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); animation-fill-mode: both; will-change: transform, opacity }
|
|
22
|
+
@media (prefers-reduced-motion: reduce) { [data-slot="apple-hello-effect-letter"] { animation: none !important } }
|
|
23
|
+
`;
|
|
24
|
+
const Frame = (0, gui_1.styled)(gui_1.XStack, {
|
|
25
|
+
name: 'AppleHelloEffect',
|
|
26
|
+
position: 'relative',
|
|
27
|
+
items: 'center',
|
|
28
|
+
justify: 'center',
|
|
29
|
+
});
|
|
30
|
+
const Letter = (0, gui_1.styled)(gui_1.SizableText, {
|
|
31
|
+
name: 'AppleHelloEffectLetter',
|
|
32
|
+
fontSize: 60,
|
|
33
|
+
lineHeight: 60,
|
|
34
|
+
fontWeight: '700',
|
|
35
|
+
});
|
|
36
|
+
function AppleHelloEffect({ text = 'Hello', duration = 2, ...props }) {
|
|
37
|
+
return ((0, jsx_runtime_1.jsxs)(Frame, { ...(0, slot_1.slot)('apple-hello-effect'), ...props, children: [(0, jsx_runtime_1.jsx)("style", { href: "apple-hello-effect", precedence: "default", children: KEYFRAMES }), [...text].map((letter, index) => ((0, jsx_runtime_1.jsx)(Letter, { ...(0, slot_1.slot)('apple-hello-effect-letter'), style: { animationDuration: `${duration}s`, animationDelay: `${index / 10}s` }, children: letter === ' ' ? '\u00A0' : letter }, index)))] }));
|
|
38
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export type AppleHelloEffectProps = React.ComponentProps<'div'> & {
|
|
3
|
+
/** The string to reveal, one letter at a time. */
|
|
4
|
+
text?: string;
|
|
5
|
+
/** Seconds each letter's own rise takes. */
|
|
6
|
+
duration?: number;
|
|
7
|
+
};
|
|
8
|
+
export declare function AppleHelloEffect({ text, duration, ...props }: AppleHelloEffectProps): React.JSX.Element;
|
|
9
|
+
//# sourceMappingURL=apple-hello-effect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apple-hello-effect.d.ts","sourceRoot":"","sources":["../../../src/backends/gui/apple-hello-effect.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAuB9B,MAAM,MAAM,qBAAqB,GAAG,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG;IAChE,kDAAkD;IAClD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,IAAc,EACd,QAAY,EACZ,GAAG,KAAK,EACT,EAAE,qBAAqB,qBAiBvB"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* AppleHelloEffect — a string that reveals itself one letter at a time. Each
|
|
5
|
+
* letter fades in while rising fifty pixels into place, and the letters start
|
|
6
|
+
* a tenth of a second apart, the way Apple's "Hello" splash plays.
|
|
7
|
+
*
|
|
8
|
+
* `text` is the string and `duration` the seconds each letter's own rise
|
|
9
|
+
* takes; the stagger rides on each letter as `animationDelay`. The keyframe
|
|
10
|
+
* rides along as a hoisted `<style>` keyed by `href`, so any number of these
|
|
11
|
+
* on a page emit it once, and under `prefers-reduced-motion` the letters stand
|
|
12
|
+
* whole and still.
|
|
13
|
+
*/
|
|
14
|
+
import { SizableText, XStack, styled } from '@hanzo/gui';
|
|
15
|
+
import { slot } from './slot.js';
|
|
16
|
+
const KEYFRAMES = `
|
|
17
|
+
@keyframes hello-rise { from { opacity: 0; transform: translateY(50px) } to { opacity: 1; transform: none } }
|
|
18
|
+
[data-slot="apple-hello-effect-letter"] { animation-name: hello-rise; animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); animation-fill-mode: both; will-change: transform, opacity }
|
|
19
|
+
@media (prefers-reduced-motion: reduce) { [data-slot="apple-hello-effect-letter"] { animation: none !important } }
|
|
20
|
+
`;
|
|
21
|
+
const Frame = styled(XStack, {
|
|
22
|
+
name: 'AppleHelloEffect',
|
|
23
|
+
position: 'relative',
|
|
24
|
+
items: 'center',
|
|
25
|
+
justify: 'center',
|
|
26
|
+
});
|
|
27
|
+
const Letter = styled(SizableText, {
|
|
28
|
+
name: 'AppleHelloEffectLetter',
|
|
29
|
+
fontSize: 60,
|
|
30
|
+
lineHeight: 60,
|
|
31
|
+
fontWeight: '700',
|
|
32
|
+
});
|
|
33
|
+
export function AppleHelloEffect({ text = 'Hello', duration = 2, ...props }) {
|
|
34
|
+
return (_jsxs(Frame, { ...slot('apple-hello-effect'), ...props, children: [_jsx("style", { href: "apple-hello-effect", precedence: "default", children: KEYFRAMES }), [...text].map((letter, index) => (_jsx(Letter, { ...slot('apple-hello-effect-letter'), style: { animationDuration: `${duration}s`, animationDelay: `${index / 10}s` }, children: letter === ' ' ? '\u00A0' : letter }, index)))] }));
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=apple-hello-effect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apple-hello-effect.js","sourceRoot":"","sources":["../../../src/backends/gui/apple-hello-effect.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ;;;;;;;;;;GAUG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAExD,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAE7B,MAAM,SAAS,GAAG;;;;CAIjB,CAAA;AAED,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE;IAC3B,IAAI,EAAE,kBAAkB;IACxB,QAAQ,EAAE,UAAU;IACpB,KAAK,EAAE,QAAQ;IACf,OAAO,EAAE,QAAQ;CAClB,CAAC,CAAA;AAEF,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,EAAE;IACjC,IAAI,EAAE,wBAAwB;IAC9B,QAAQ,EAAE,EAAE;IACZ,UAAU,EAAE,EAAE;IACd,UAAU,EAAE,KAAK;CAClB,CAAC,CAAA;AASF,MAAM,UAAU,gBAAgB,CAAC,EAC/B,IAAI,GAAG,OAAO,EACd,QAAQ,GAAG,CAAC,EACZ,GAAG,KAAK,EACc;IACtB,OAAO,CACL,MAAC,KAAK,OAAK,IAAI,CAAC,oBAAoB,CAAC,KAAO,KAA4C,aACtF,gBAAO,IAAI,EAAC,oBAAoB,EAAC,UAAU,EAAC,SAAS,YAClD,SAAS,GACJ,EACP,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAChC,KAAC,MAAM,OAED,IAAI,CAAC,2BAA2B,CAAC,EACrC,KAAK,EAAE,EAAE,iBAAiB,EAAE,GAAG,QAAQ,GAAG,EAAE,cAAc,EAAE,GAAG,KAAK,GAAG,EAAE,GAAG,EAAE,YAE7E,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,IAJ9B,KAAK,CAKH,CACV,CAAC,IACI,CACT,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
'use client';"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.Banner = Banner;
|
|
5
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
|
+
/**
|
|
7
|
+
* Banner — a full-width strip anchored to an edge of its container: a leading
|
|
8
|
+
* icon, a message, and an optional close button, in one of five variants
|
|
9
|
+
* (`default`, `info`, `success`, `warning`, `error`).
|
|
10
|
+
*
|
|
11
|
+
* The icon is the first child when that child is not itself a string, the same
|
|
12
|
+
* convention `Alert` uses — it sits absolutely at the left edge and the message
|
|
13
|
+
* column indents to clear it. Surface, icon and text are three styled parts
|
|
14
|
+
* sharing one `variant` through a styled context, so a variant reaches all
|
|
15
|
+
* three without any part reading it twice by hand.
|
|
16
|
+
*
|
|
17
|
+
* `onClose` only reports that the close button was pressed. A Banner carries no
|
|
18
|
+
* visibility state of its own; whether the strip stays mounted is the caller's
|
|
19
|
+
* decision.
|
|
20
|
+
*
|
|
21
|
+
* Message and icon paint from the hue's text rungs — step 12 for the message,
|
|
22
|
+
* step 11 for the icon — because step 9 is a fill: on the light theme it reads
|
|
23
|
+
* at 1.2:1 for yellow and about 3:1 for blue and green over the step-2 ground.
|
|
24
|
+
*/
|
|
25
|
+
const react_1 = require("react");
|
|
26
|
+
const gui_1 = require("@hanzo/gui");
|
|
27
|
+
const lucide_icons_2_1 = require("@hanzogui/lucide-icons-2");
|
|
28
|
+
const slot_1 = require("./slot.cjs");
|
|
29
|
+
const gesture_1 = require("./gesture.cjs");
|
|
30
|
+
const button_1 = require("./button.cjs");
|
|
31
|
+
const ICON = 16;
|
|
32
|
+
const ICON_GUTTER = 28;
|
|
33
|
+
const CLOSE = 24;
|
|
34
|
+
const BannerContext = /* @__PURE__ */ (0, gui_1.createStyledContext)({
|
|
35
|
+
variant: 'default',
|
|
36
|
+
});
|
|
37
|
+
const BannerFrame = (0, gui_1.styled)(gui_1.YStack, {
|
|
38
|
+
name: 'Banner',
|
|
39
|
+
context: BannerContext,
|
|
40
|
+
position: 'relative',
|
|
41
|
+
width: '100%',
|
|
42
|
+
borderBottomWidth: 1,
|
|
43
|
+
borderColor: '$borderColor',
|
|
44
|
+
bg: '$background',
|
|
45
|
+
px: '$4',
|
|
46
|
+
py: '$3',
|
|
47
|
+
variants: {
|
|
48
|
+
variant: {
|
|
49
|
+
default: {},
|
|
50
|
+
info: { borderColor: '$blue9', bg: '$blue2' },
|
|
51
|
+
success: { borderColor: '$green9', bg: '$green2' },
|
|
52
|
+
warning: { borderColor: '$yellow9', bg: '$yellow2' },
|
|
53
|
+
error: { borderColor: '$red9', bg: '$red2' },
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
defaultVariants: { variant: 'default' },
|
|
57
|
+
});
|
|
58
|
+
const BannerText = (0, gui_1.styled)(gui_1.SizableText, {
|
|
59
|
+
name: 'BannerText',
|
|
60
|
+
context: BannerContext,
|
|
61
|
+
render: 'div',
|
|
62
|
+
size: '$2',
|
|
63
|
+
color: '$ink',
|
|
64
|
+
variants: {
|
|
65
|
+
variant: {
|
|
66
|
+
default: {},
|
|
67
|
+
info: { color: '$blue12' },
|
|
68
|
+
success: { color: '$green12' },
|
|
69
|
+
warning: { color: '$yellow12' },
|
|
70
|
+
error: { color: '$red12' },
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
// A Text host because a View takes no `color`, and an svg child paints in
|
|
75
|
+
// `currentColor`.
|
|
76
|
+
const IconSlot = (0, gui_1.styled)(gui_1.SizableText, {
|
|
77
|
+
name: 'BannerIcon',
|
|
78
|
+
context: BannerContext,
|
|
79
|
+
display: 'flex',
|
|
80
|
+
position: 'absolute',
|
|
81
|
+
t: '$3',
|
|
82
|
+
l: '$4',
|
|
83
|
+
width: ICON,
|
|
84
|
+
height: ICON,
|
|
85
|
+
items: 'center',
|
|
86
|
+
justify: 'center',
|
|
87
|
+
color: '$ink',
|
|
88
|
+
variants: {
|
|
89
|
+
variant: {
|
|
90
|
+
default: {},
|
|
91
|
+
info: { color: '$blue11' },
|
|
92
|
+
success: { color: '$green11' },
|
|
93
|
+
warning: { color: '$yellow11' },
|
|
94
|
+
error: { color: '$red11' },
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
function Banner({ variant = 'default', onClose, children, ...props }) {
|
|
99
|
+
const resolved = variant ?? 'default';
|
|
100
|
+
const items = react_1.Children.toArray(children);
|
|
101
|
+
const head = items[0];
|
|
102
|
+
const icon = (0, react_1.isValidElement)(head) ? head : null;
|
|
103
|
+
const body = icon ? items.slice(1) : items;
|
|
104
|
+
return ((0, jsx_runtime_1.jsxs)(BannerFrame, { role: "alert", variant: resolved, ...(0, slot_1.slot)('banner'), "data-variant": resolved, ...props, children: [icon ? ((0, jsx_runtime_1.jsx)(IconSlot, { ...(0, slot_1.slot)('banner-icon'), children: icon })) : null, (0, jsx_runtime_1.jsx)(BannerText, { ...(0, slot_1.slot)('banner-message'), pl: icon ? ICON_GUTTER : 0, pr: onClose ? CLOSE + 12 : 0, children: body }), onClose ? ((0, jsx_runtime_1.jsx)(button_1.Button, { ...(0, slot_1.slot)('banner-close'), variant: "ghost", size: "icon", minH: CLOSE, minW: CLOSE, ...(0, gesture_1.touch)(CLOSE),
|
|
105
|
+
// After `touch`, which sets `position: relative` on web to host its
|
|
106
|
+
// hit-area overlay; an absolute box hosts it just as well.
|
|
107
|
+
position: "absolute", t: "$3", r: "$4", "aria-label": "Close", onPress: onClose, children: (0, jsx_runtime_1.jsx)(lucide_icons_2_1.X, { size: 16 }) })) : null] }));
|
|
108
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Banner — a full-width strip anchored to an edge of its container: a leading
|
|
3
|
+
* icon, a message, and an optional close button, in one of five variants
|
|
4
|
+
* (`default`, `info`, `success`, `warning`, `error`).
|
|
5
|
+
*
|
|
6
|
+
* The icon is the first child when that child is not itself a string, the same
|
|
7
|
+
* convention `Alert` uses — it sits absolutely at the left edge and the message
|
|
8
|
+
* column indents to clear it. Surface, icon and text are three styled parts
|
|
9
|
+
* sharing one `variant` through a styled context, so a variant reaches all
|
|
10
|
+
* three without any part reading it twice by hand.
|
|
11
|
+
*
|
|
12
|
+
* `onClose` only reports that the close button was pressed. A Banner carries no
|
|
13
|
+
* visibility state of its own; whether the strip stays mounted is the caller's
|
|
14
|
+
* decision.
|
|
15
|
+
*
|
|
16
|
+
* Message and icon paint from the hue's text rungs — step 12 for the message,
|
|
17
|
+
* step 11 for the icon — because step 9 is a fill: on the light theme it reads
|
|
18
|
+
* at 1.2:1 for yellow and about 3:1 for blue and green over the step-2 ground.
|
|
19
|
+
*/
|
|
20
|
+
import { type ComponentProps } from 'react';
|
|
21
|
+
export type BannerVariant = 'default' | 'info' | 'success' | 'warning' | 'error';
|
|
22
|
+
declare const BannerFrame: import("@hanzogui/web").GuiComponent<import("@hanzogui/web").TamaDefer, import("@hanzogui/web").GuiElement, import("@hanzogui/core").RNGuiViewNonStyleProps, import("@hanzogui/web").StackStyleBase, {
|
|
23
|
+
elevation?: number | import("@hanzogui/web").SizeTokens | undefined;
|
|
24
|
+
fullscreen?: boolean | undefined;
|
|
25
|
+
variant?: "default" | "error" | "info" | "success" | "warning" | undefined;
|
|
26
|
+
}, import("@hanzogui/web").StaticConfigPublic>;
|
|
27
|
+
export type BannerProps = Omit<ComponentProps<typeof BannerFrame>, 'variant'> & {
|
|
28
|
+
variant?: BannerVariant | null;
|
|
29
|
+
onClose?: () => void;
|
|
30
|
+
};
|
|
31
|
+
export declare function Banner({ variant, onClose, children, ...props }: BannerProps): import("react").JSX.Element;
|
|
32
|
+
export {};
|
|
33
|
+
//# sourceMappingURL=banner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"banner.d.ts","sourceRoot":"","sources":["../../../src/backends/gui/banner.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAA4B,KAAK,cAAc,EAAE,MAAM,OAAO,CAAA;AAOrE,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAA;AAUhF,QAAA,MAAM,WAAW;;;;8CAsBf,CAAA;AA8CF,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,WAAW,CAAC,EAAE,SAAS,CAAC,GAAG;IAC9E,OAAO,CAAC,EAAE,aAAa,GAAG,IAAI,CAAA;IAC9B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CACrB,CAAA;AAED,wBAAgB,MAAM,CAAC,EAAE,OAAmB,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,WAAW,+BA0CvF"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* Banner — a full-width strip anchored to an edge of its container: a leading
|
|
5
|
+
* icon, a message, and an optional close button, in one of five variants
|
|
6
|
+
* (`default`, `info`, `success`, `warning`, `error`).
|
|
7
|
+
*
|
|
8
|
+
* The icon is the first child when that child is not itself a string, the same
|
|
9
|
+
* convention `Alert` uses — it sits absolutely at the left edge and the message
|
|
10
|
+
* column indents to clear it. Surface, icon and text are three styled parts
|
|
11
|
+
* sharing one `variant` through a styled context, so a variant reaches all
|
|
12
|
+
* three without any part reading it twice by hand.
|
|
13
|
+
*
|
|
14
|
+
* `onClose` only reports that the close button was pressed. A Banner carries no
|
|
15
|
+
* visibility state of its own; whether the strip stays mounted is the caller's
|
|
16
|
+
* decision.
|
|
17
|
+
*
|
|
18
|
+
* Message and icon paint from the hue's text rungs — step 12 for the message,
|
|
19
|
+
* step 11 for the icon — because step 9 is a fill: on the light theme it reads
|
|
20
|
+
* at 1.2:1 for yellow and about 3:1 for blue and green over the step-2 ground.
|
|
21
|
+
*/
|
|
22
|
+
import { Children, isValidElement } from 'react';
|
|
23
|
+
import { SizableText, YStack, createStyledContext, styled } from '@hanzo/gui';
|
|
24
|
+
import { X } from '@hanzogui/lucide-icons-2';
|
|
25
|
+
import { slot } from './slot.js';
|
|
26
|
+
import { touch } from './gesture.js';
|
|
27
|
+
import { Button } from './button.js';
|
|
28
|
+
const ICON = 16;
|
|
29
|
+
const ICON_GUTTER = 28;
|
|
30
|
+
const CLOSE = 24;
|
|
31
|
+
const BannerContext = /* @__PURE__ */ createStyledContext({
|
|
32
|
+
variant: 'default',
|
|
33
|
+
});
|
|
34
|
+
const BannerFrame = styled(YStack, {
|
|
35
|
+
name: 'Banner',
|
|
36
|
+
context: BannerContext,
|
|
37
|
+
position: 'relative',
|
|
38
|
+
width: '100%',
|
|
39
|
+
borderBottomWidth: 1,
|
|
40
|
+
borderColor: '$borderColor',
|
|
41
|
+
bg: '$background',
|
|
42
|
+
px: '$4',
|
|
43
|
+
py: '$3',
|
|
44
|
+
variants: {
|
|
45
|
+
variant: {
|
|
46
|
+
default: {},
|
|
47
|
+
info: { borderColor: '$blue9', bg: '$blue2' },
|
|
48
|
+
success: { borderColor: '$green9', bg: '$green2' },
|
|
49
|
+
warning: { borderColor: '$yellow9', bg: '$yellow2' },
|
|
50
|
+
error: { borderColor: '$red9', bg: '$red2' },
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
defaultVariants: { variant: 'default' },
|
|
54
|
+
});
|
|
55
|
+
const BannerText = styled(SizableText, {
|
|
56
|
+
name: 'BannerText',
|
|
57
|
+
context: BannerContext,
|
|
58
|
+
render: 'div',
|
|
59
|
+
size: '$2',
|
|
60
|
+
color: '$ink',
|
|
61
|
+
variants: {
|
|
62
|
+
variant: {
|
|
63
|
+
default: {},
|
|
64
|
+
info: { color: '$blue12' },
|
|
65
|
+
success: { color: '$green12' },
|
|
66
|
+
warning: { color: '$yellow12' },
|
|
67
|
+
error: { color: '$red12' },
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
// A Text host because a View takes no `color`, and an svg child paints in
|
|
72
|
+
// `currentColor`.
|
|
73
|
+
const IconSlot = styled(SizableText, {
|
|
74
|
+
name: 'BannerIcon',
|
|
75
|
+
context: BannerContext,
|
|
76
|
+
display: 'flex',
|
|
77
|
+
position: 'absolute',
|
|
78
|
+
t: '$3',
|
|
79
|
+
l: '$4',
|
|
80
|
+
width: ICON,
|
|
81
|
+
height: ICON,
|
|
82
|
+
items: 'center',
|
|
83
|
+
justify: 'center',
|
|
84
|
+
color: '$ink',
|
|
85
|
+
variants: {
|
|
86
|
+
variant: {
|
|
87
|
+
default: {},
|
|
88
|
+
info: { color: '$blue11' },
|
|
89
|
+
success: { color: '$green11' },
|
|
90
|
+
warning: { color: '$yellow11' },
|
|
91
|
+
error: { color: '$red11' },
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
export function Banner({ variant = 'default', onClose, children, ...props }) {
|
|
96
|
+
const resolved = variant ?? 'default';
|
|
97
|
+
const items = Children.toArray(children);
|
|
98
|
+
const head = items[0];
|
|
99
|
+
const icon = isValidElement(head) ? head : null;
|
|
100
|
+
const body = icon ? items.slice(1) : items;
|
|
101
|
+
return (_jsxs(BannerFrame, { role: "alert", variant: resolved, ...slot('banner'), "data-variant": resolved, ...props, children: [icon ? (_jsx(IconSlot, { ...slot('banner-icon'), children: icon })) : null, _jsx(BannerText, { ...slot('banner-message'), pl: icon ? ICON_GUTTER : 0, pr: onClose ? CLOSE + 12 : 0, children: body }), onClose ? (_jsx(Button, { ...slot('banner-close'), variant: "ghost", size: "icon", minH: CLOSE, minW: CLOSE, ...touch(CLOSE),
|
|
102
|
+
// After `touch`, which sets `position: relative` on web to host its
|
|
103
|
+
// hit-area overlay; an absolute box hosts it just as well.
|
|
104
|
+
position: "absolute", t: "$3", r: "$4", "aria-label": "Close", onPress: onClose, children: _jsx(X, { size: 16 }) })) : null] }));
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=banner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"banner.js","sourceRoot":"","sources":["../../../src/backends/gui/banner.tsx"],"names":[],"mappings":"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"}
|