aporia 0.2.0 → 0.2.5
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 +21 -8
- package/dist/ThemeProvider.d.ts.map +1 -1
- package/dist/components/Category.d.ts.map +1 -1
- package/dist/components/SelectRow.d.ts +17 -0
- package/dist/components/SelectRow.d.ts.map +1 -0
- package/dist/{style.css → index.css} +420 -16
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +147 -11
- package/dist/index.js.map +1 -1
- package/package.json +9 -4
package/dist/index.js
CHANGED
|
@@ -2,9 +2,9 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
-
import t, { useContext, createContext, useId, useState, useCallback,
|
|
6
|
-
import { useMotionValue, useSpring, useTransform
|
|
7
|
-
import { Popover } from "@base-ui/react";
|
|
5
|
+
import t, { useContext, createContext, useId, useState, useCallback, useRef, useLayoutEffect, useEffect, useMemo } from "react";
|
|
6
|
+
import { motion, useMotionValue, useSpring, useTransform } from "motion/react";
|
|
7
|
+
import { Popover, Select } from "@base-ui/react";
|
|
8
8
|
function Panel({ children, className, ...rest }) {
|
|
9
9
|
return /* @__PURE__ */ jsx(
|
|
10
10
|
"div",
|
|
@@ -25,6 +25,12 @@ function CategoryDisabledProvider({
|
|
|
25
25
|
function useCategoryDisabled() {
|
|
26
26
|
return useContext(CategoryDisabledContext);
|
|
27
27
|
}
|
|
28
|
+
const categoryBodyTransition = {
|
|
29
|
+
type: "spring",
|
|
30
|
+
stiffness: 1e3,
|
|
31
|
+
damping: 44,
|
|
32
|
+
mass: 0.28
|
|
33
|
+
};
|
|
28
34
|
function Category({
|
|
29
35
|
title,
|
|
30
36
|
children,
|
|
@@ -47,11 +53,26 @@ function Category({
|
|
|
47
53
|
},
|
|
48
54
|
[collapsedProp, onCollapsedChange]
|
|
49
55
|
);
|
|
56
|
+
const innerRef = useRef(null);
|
|
57
|
+
const [bodyHeightPx, setBodyHeightPx] = useState(0);
|
|
58
|
+
useLayoutEffect(() => {
|
|
59
|
+
const inner = innerRef.current;
|
|
60
|
+
if (!inner) return;
|
|
61
|
+
const measure = () => {
|
|
62
|
+
setBodyHeightPx(inner.scrollHeight);
|
|
63
|
+
};
|
|
64
|
+
measure();
|
|
65
|
+
const ro = new ResizeObserver(measure);
|
|
66
|
+
ro.observe(inner);
|
|
67
|
+
return () => ro.disconnect();
|
|
68
|
+
}, []);
|
|
69
|
+
const openBodyHeight = Math.max(bodyHeightPx, 1);
|
|
50
70
|
return /* @__PURE__ */ jsxs(
|
|
51
71
|
"section",
|
|
52
72
|
{
|
|
53
73
|
className: ["category", className].filter(Boolean).join(" "),
|
|
54
74
|
"data-disabled": disabled ? "true" : "false",
|
|
75
|
+
"data-collapsed": collapsed ? "true" : "false",
|
|
55
76
|
children: [
|
|
56
77
|
/* @__PURE__ */ jsxs("div", { className: "categoryHeader", children: [
|
|
57
78
|
/* @__PURE__ */ jsxs("div", { className: "categoryHeaderStart", children: [
|
|
@@ -88,7 +109,14 @@ function Category({
|
|
|
88
109
|
)
|
|
89
110
|
}
|
|
90
111
|
) }),
|
|
91
|
-
/* @__PURE__ */ jsx(
|
|
112
|
+
/* @__PURE__ */ jsx(
|
|
113
|
+
"h2",
|
|
114
|
+
{
|
|
115
|
+
className: "categoryTitle",
|
|
116
|
+
id: `${bodyId}-label`,
|
|
117
|
+
children: title
|
|
118
|
+
}
|
|
119
|
+
)
|
|
92
120
|
] }),
|
|
93
121
|
onDisabledChange ? /* @__PURE__ */ jsx(
|
|
94
122
|
"button",
|
|
@@ -105,15 +133,40 @@ function Category({
|
|
|
105
133
|
) : null
|
|
106
134
|
] }),
|
|
107
135
|
/* @__PURE__ */ jsx(CategoryDisabledProvider, { value: disabled, children: /* @__PURE__ */ jsx(
|
|
108
|
-
|
|
136
|
+
motion.div,
|
|
109
137
|
{
|
|
110
138
|
id: bodyId,
|
|
111
|
-
className: "categoryBody
|
|
139
|
+
className: "categoryBody",
|
|
112
140
|
role: "region",
|
|
113
141
|
"aria-labelledby": `${bodyId}-label`,
|
|
114
|
-
hidden: collapsed,
|
|
115
142
|
"aria-hidden": collapsed,
|
|
116
|
-
|
|
143
|
+
initial: false,
|
|
144
|
+
animate: {
|
|
145
|
+
height: collapsed ? 0 : openBodyHeight,
|
|
146
|
+
marginTop: collapsed ? -8 : 0,
|
|
147
|
+
opacity: collapsed ? 0 : 1
|
|
148
|
+
},
|
|
149
|
+
transition: {
|
|
150
|
+
height: categoryBodyTransition,
|
|
151
|
+
marginTop: categoryBodyTransition,
|
|
152
|
+
// Fade out quickly while collapsing so controls don’t peek; gentler fade-in on expand.
|
|
153
|
+
opacity: collapsed ? { duration: 0.09, ease: "easeIn" } : { duration: 0.15, ease: "easeOut" }
|
|
154
|
+
},
|
|
155
|
+
style: {
|
|
156
|
+
/* visible so SliderRow edge stretch (width/margin motion) isn’t clipped; collapse hides via height + opacity + inert */
|
|
157
|
+
overflow: "visible",
|
|
158
|
+
minHeight: 0,
|
|
159
|
+
boxSizing: "border-box"
|
|
160
|
+
},
|
|
161
|
+
inert: collapsed,
|
|
162
|
+
children: /* @__PURE__ */ jsx(
|
|
163
|
+
"div",
|
|
164
|
+
{
|
|
165
|
+
ref: innerRef,
|
|
166
|
+
className: "categoryBodyInner sliderGroup",
|
|
167
|
+
children
|
|
168
|
+
}
|
|
169
|
+
)
|
|
117
170
|
}
|
|
118
171
|
) })
|
|
119
172
|
]
|
|
@@ -451,9 +504,6 @@ function useSliderOverlapDebugEnabled() {
|
|
|
451
504
|
const ThemeContext = createContext(null);
|
|
452
505
|
function ThemeProvider({ children }) {
|
|
453
506
|
const theme = "dark";
|
|
454
|
-
useEffect(() => {
|
|
455
|
-
document.documentElement.dataset.theme = theme;
|
|
456
|
-
}, [theme]);
|
|
457
507
|
return /* @__PURE__ */ jsx(ThemeContext.Provider, { value: { theme }, children });
|
|
458
508
|
}
|
|
459
509
|
function useTheme() {
|
|
@@ -2101,6 +2151,91 @@ function ToggleRow({ label, checked, onChange, disabled: disabledProp }) {
|
|
|
2101
2151
|
}
|
|
2102
2152
|
) });
|
|
2103
2153
|
}
|
|
2154
|
+
function SelectRow({
|
|
2155
|
+
label,
|
|
2156
|
+
options,
|
|
2157
|
+
value,
|
|
2158
|
+
onChange,
|
|
2159
|
+
placeholder = "Choose…",
|
|
2160
|
+
disabled: disabledProp,
|
|
2161
|
+
name
|
|
2162
|
+
}) {
|
|
2163
|
+
const categoryDisabled = useCategoryDisabled();
|
|
2164
|
+
const disabled = Boolean(disabledProp || categoryDisabled);
|
|
2165
|
+
const [menuOpen, setMenuOpen] = useState(false);
|
|
2166
|
+
const wrapRef = useRef(null);
|
|
2167
|
+
const [anchorWidth, setAnchorWidth] = useState(0);
|
|
2168
|
+
useLayoutEffect(() => {
|
|
2169
|
+
const el = wrapRef.current;
|
|
2170
|
+
if (!el) return;
|
|
2171
|
+
const ro = new ResizeObserver(() => {
|
|
2172
|
+
setAnchorWidth(el.offsetWidth);
|
|
2173
|
+
});
|
|
2174
|
+
ro.observe(el);
|
|
2175
|
+
setAnchorWidth(el.offsetWidth);
|
|
2176
|
+
return () => ro.disconnect();
|
|
2177
|
+
}, []);
|
|
2178
|
+
const portalStyle = anchorWidth > 0 ? { "--select-anchor-width": `${anchorWidth}px` } : void 0;
|
|
2179
|
+
const items = useMemo(
|
|
2180
|
+
() => Object.fromEntries(options.map((o) => [o.value, o.label])),
|
|
2181
|
+
[options]
|
|
2182
|
+
);
|
|
2183
|
+
return /* @__PURE__ */ jsx(
|
|
2184
|
+
"div",
|
|
2185
|
+
{
|
|
2186
|
+
ref: wrapRef,
|
|
2187
|
+
className: "selectRowWrap",
|
|
2188
|
+
"data-disabled": disabled ? "true" : "false",
|
|
2189
|
+
children: /* @__PURE__ */ jsxs(
|
|
2190
|
+
Select.Root,
|
|
2191
|
+
{
|
|
2192
|
+
name,
|
|
2193
|
+
items,
|
|
2194
|
+
value,
|
|
2195
|
+
onValueChange: (next) => {
|
|
2196
|
+
if (next != null) onChange(next);
|
|
2197
|
+
},
|
|
2198
|
+
onOpenChange: (open) => setMenuOpen(open),
|
|
2199
|
+
disabled,
|
|
2200
|
+
modal: false,
|
|
2201
|
+
children: [
|
|
2202
|
+
/* @__PURE__ */ jsxs(Select.Trigger, { className: "selectCard", "data-menu-open": menuOpen ? "true" : "false", children: [
|
|
2203
|
+
/* @__PURE__ */ jsx("span", { className: "selectLabel", children: label }),
|
|
2204
|
+
/* @__PURE__ */ jsxs("span", { className: "selectValueZone", children: [
|
|
2205
|
+
/* @__PURE__ */ jsx(Select.Value, { placeholder, className: "selectValue" }),
|
|
2206
|
+
/* @__PURE__ */ jsx(Select.Icon, { className: "selectIcon", "aria-hidden": true, children: /* @__PURE__ */ jsx("svg", { width: "12", height: "12", viewBox: "0 0 12 12", className: "selectChevronSvg", children: /* @__PURE__ */ jsx(
|
|
2207
|
+
"path",
|
|
2208
|
+
{
|
|
2209
|
+
d: "M3 4.5L6 7.5L9 4.5",
|
|
2210
|
+
fill: "none",
|
|
2211
|
+
stroke: "currentColor",
|
|
2212
|
+
strokeWidth: "1.5",
|
|
2213
|
+
strokeLinecap: "round",
|
|
2214
|
+
strokeLinejoin: "round"
|
|
2215
|
+
}
|
|
2216
|
+
) }) })
|
|
2217
|
+
] })
|
|
2218
|
+
] }),
|
|
2219
|
+
/* @__PURE__ */ jsx(Select.Portal, { className: "selectPortal", style: portalStyle, children: /* @__PURE__ */ jsx(
|
|
2220
|
+
Select.Positioner,
|
|
2221
|
+
{
|
|
2222
|
+
className: "selectPositioner",
|
|
2223
|
+
style: portalStyle,
|
|
2224
|
+
positionMethod: "fixed",
|
|
2225
|
+
side: "bottom",
|
|
2226
|
+
align: "end",
|
|
2227
|
+
sideOffset: 6,
|
|
2228
|
+
alignItemWithTrigger: false,
|
|
2229
|
+
collisionAvoidance: { side: "flip", align: "shift", fallbackAxisSide: "none" },
|
|
2230
|
+
children: /* @__PURE__ */ jsx(Select.Popup, { className: "selectPopup", children: /* @__PURE__ */ jsx(Select.List, { className: "selectList", children: options.map((opt) => /* @__PURE__ */ jsx(Select.Item, { value: opt.value, className: "selectItem", children: /* @__PURE__ */ jsx(Select.ItemText, { className: "selectItemText", children: opt.label }) }, opt.value)) }) })
|
|
2231
|
+
}
|
|
2232
|
+
) })
|
|
2233
|
+
]
|
|
2234
|
+
}
|
|
2235
|
+
)
|
|
2236
|
+
}
|
|
2237
|
+
);
|
|
2238
|
+
}
|
|
2104
2239
|
function generateAestheticGradient(stopCount) {
|
|
2105
2240
|
const baseHue = Math.random() * 360;
|
|
2106
2241
|
const hueShift = 25 + Math.random() * 35;
|
|
@@ -2402,6 +2537,7 @@ export {
|
|
|
2402
2537
|
GradientPicker,
|
|
2403
2538
|
GradientRow,
|
|
2404
2539
|
Panel,
|
|
2540
|
+
SelectRow,
|
|
2405
2541
|
SliderOverlapDebugProvider,
|
|
2406
2542
|
SliderRow,
|
|
2407
2543
|
SwatchPopover,
|