@mlola-ui/registry 1.1.6 → 1.1.7
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/components/accordion.json +2 -2
- package/components/alert.json +1 -1
- package/components/app-shell.json +1 -1
- package/components/badge.json +1 -1
- package/components/breadcrumb.json +1 -1
- package/components/button.json +1 -1
- package/components/calendar.json +1 -1
- package/components/carousel.json +2 -2
- package/components/checkbox.json +1 -1
- package/components/color-picker.json +1 -1
- package/components/combobox.json +1 -1
- package/components/command-menu.json +1 -1
- package/components/context-menu.json +2 -2
- package/components/copy-button.json +1 -1
- package/components/date-picker.json +1 -1
- package/components/dropdown-menu.json +2 -2
- package/components/dropzone.json +1 -1
- package/components/hover-card.json +1 -1
- package/components/modal.json +2 -2
- package/components/number-input.json +1 -1
- package/components/pagination.json +1 -1
- package/components/password-input.json +2 -2
- package/components/popover.json +1 -1
- package/components/resizable.json +1 -1
- package/components/segmented-control.json +1 -1
- package/components/select.json +2 -2
- package/components/sheet.json +2 -2
- package/components/slider.json +2 -2
- package/components/stepper.json +1 -1
- package/components/tabs.json +1 -1
- package/components/tag-input.json +1 -1
- package/components/time-picker.json +1 -1
- package/components/timeline.json +1 -1
- package/components/toast.json +1 -1
- package/components/tooltip.json +1 -1
- package/components/tour.json +2 -2
- package/generated/catalog.js +44 -44
- package/index.json +1 -1
- package/package.json +1 -1
- package/snapshot/index.json +47 -47
- package/snapshot/items/components/accordion.json +2 -2
- package/snapshot/items/components/alert.json +1 -1
- package/snapshot/items/components/app-shell.json +1 -1
- package/snapshot/items/components/badge.json +1 -1
- package/snapshot/items/components/breadcrumb.json +1 -1
- package/snapshot/items/components/button.json +1 -1
- package/snapshot/items/components/calendar.json +1 -1
- package/snapshot/items/components/carousel.json +2 -2
- package/snapshot/items/components/checkbox.json +1 -1
- package/snapshot/items/components/color-picker.json +1 -1
- package/snapshot/items/components/combobox.json +1 -1
- package/snapshot/items/components/command-menu.json +1 -1
- package/snapshot/items/components/context-menu.json +2 -2
- package/snapshot/items/components/copy-button.json +1 -1
- package/snapshot/items/components/date-picker.json +1 -1
- package/snapshot/items/components/dropdown-menu.json +2 -2
- package/snapshot/items/components/dropzone.json +1 -1
- package/snapshot/items/components/hover-card.json +1 -1
- package/snapshot/items/components/modal.json +2 -2
- package/snapshot/items/components/number-input.json +1 -1
- package/snapshot/items/components/pagination.json +1 -1
- package/snapshot/items/components/password-input.json +2 -2
- package/snapshot/items/components/popover.json +1 -1
- package/snapshot/items/components/resizable.json +1 -1
- package/snapshot/items/components/segmented-control.json +1 -1
- package/snapshot/items/components/select.json +2 -2
- package/snapshot/items/components/sheet.json +2 -2
- package/snapshot/items/components/slider.json +2 -2
- package/snapshot/items/components/stepper.json +1 -1
- package/snapshot/items/components/tabs.json +1 -1
- package/snapshot/items/components/tag-input.json +1 -1
- package/snapshot/items/components/time-picker.json +1 -1
- package/snapshot/items/components/timeline.json +1 -1
- package/snapshot/items/components/toast.json +1 -1
- package/snapshot/items/components/tooltip.json +1 -1
- package/snapshot/items/components/tour.json +2 -2
- package/snapshot/source/packages/components/resizable/resizable.tsx +34 -6
- package/snapshot/source/packages/components/slider/slider.tsx +34 -16
- package/snapshot/source-manifest.json +2 -2
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"path": "packages/components/resizable/resizable.tsx",
|
|
61
61
|
"target": "{{aliases.components}}/resizable.tsx",
|
|
62
62
|
"type": "registry:ui",
|
|
63
|
-
"integrity": "sha256-
|
|
63
|
+
"integrity": "sha256-RFBpg/a2O82mmx+O5wT+um+y3y2w0rUMJJdBzRu9ONU="
|
|
64
64
|
}
|
|
65
65
|
],
|
|
66
66
|
"themeContract": {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"input"
|
|
21
21
|
],
|
|
22
22
|
"engineDependencies": {
|
|
23
|
-
"@mlola-ui/behavior": "^1.1.
|
|
23
|
+
"@mlola-ui/behavior": "^1.1.7"
|
|
24
24
|
},
|
|
25
25
|
"options": [
|
|
26
26
|
{
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"path": "packages/components/slider/slider.tsx",
|
|
50
50
|
"target": "{{aliases.components}}/slider.tsx",
|
|
51
51
|
"type": "registry:ui",
|
|
52
|
-
"integrity": "sha256-
|
|
52
|
+
"integrity": "sha256-o37Xi4J8+d/fhWFf2LdpPluuKDVXECNl4quKTlrqCU4="
|
|
53
53
|
}
|
|
54
54
|
],
|
|
55
55
|
"themeContract": {
|
|
@@ -70,7 +70,9 @@ export function Resizable({
|
|
|
70
70
|
const [current, setCurrent] = useControllableState({ value: size, defaultValue: defaultSize, onChange: onSizeChange });
|
|
71
71
|
const [folded, setFolded] = useControllableState({ value: collapsed, defaultValue: defaultCollapsed, onChange: onCollapsedChange });
|
|
72
72
|
const root = React.useRef<HTMLDivElement>(null);
|
|
73
|
-
|
|
73
|
+
// The drag in progress: where on the handle it was grabbed, and the layout to
|
|
74
|
+
// put back if it is canceled.
|
|
75
|
+
const drag = React.useRef<{ id: number; grab: number; size: number; folded: boolean } | null>(null);
|
|
74
76
|
const horizontal = direction === "horizontal";
|
|
75
77
|
const set = (value: number) => setCurrent(Math.round(clamp(value, min, max) * 10) / 10);
|
|
76
78
|
const isFolded = collapsible && folded;
|
|
@@ -93,11 +95,12 @@ export function Resizable({
|
|
|
93
95
|
}
|
|
94
96
|
}, [storageKey, current, isFolded]);
|
|
95
97
|
|
|
96
|
-
const fromPointer = (event: React.PointerEvent) => {
|
|
98
|
+
const fromPointer = (event: React.PointerEvent, grab: number) => {
|
|
97
99
|
const rect = root.current?.getBoundingClientRect();
|
|
98
100
|
if (!rect) return;
|
|
99
101
|
const total = horizontal ? rect.width : rect.height;
|
|
100
|
-
|
|
102
|
+
// Keep the point that was grabbed under the pointer, so the handle does not jump.
|
|
103
|
+
const offset = (horizontal ? event.clientX - rect.left : event.clientY - rect.top) - grab;
|
|
101
104
|
const along = anchor === "first" ? offset : total - offset;
|
|
102
105
|
const value = units === "pixels" ? along : (along / total) * 100;
|
|
103
106
|
// Dragging well past the minimum folds a collapsible pane; dragging back unfolds it.
|
|
@@ -138,20 +141,45 @@ export function Resizable({
|
|
|
138
141
|
aria-valuetext={isFolded ? "Collapsed" : undefined}
|
|
139
142
|
className="ml-resizable-handle"
|
|
140
143
|
onPointerDown={(event) => {
|
|
141
|
-
|
|
144
|
+
if (event.button !== 0) return;
|
|
145
|
+
// No text selection in the panes while the handle moves; focus stays for the keyboard.
|
|
146
|
+
event.preventDefault();
|
|
147
|
+
event.currentTarget.focus();
|
|
148
|
+
// Measured from the edge the size is measured to: the handle's near
|
|
149
|
+
// edge for the first pane, its far edge for the second.
|
|
150
|
+
const handle = event.currentTarget.getBoundingClientRect();
|
|
151
|
+
const edge = horizontal ? (anchor === "first" ? handle.left : handle.right) : anchor === "first" ? handle.top : handle.bottom;
|
|
152
|
+
const grab = (horizontal ? event.clientX : event.clientY) - edge;
|
|
153
|
+
drag.current = { id: event.pointerId, grab, size: current, folded: isFolded };
|
|
142
154
|
event.currentTarget.setPointerCapture(event.pointerId);
|
|
143
155
|
}}
|
|
144
156
|
onPointerMove={(event) => {
|
|
145
|
-
if (
|
|
157
|
+
if (drag.current?.id === event.pointerId) fromPointer(event, drag.current.grab);
|
|
146
158
|
}}
|
|
147
159
|
onPointerUp={() => {
|
|
148
|
-
|
|
160
|
+
drag.current = null;
|
|
161
|
+
}}
|
|
162
|
+
// A drag the browser takes away ends; the pointer passing over the handle later moves nothing.
|
|
163
|
+
onPointerCancel={() => {
|
|
164
|
+
drag.current = null;
|
|
165
|
+
}}
|
|
166
|
+
onLostPointerCapture={() => {
|
|
167
|
+
drag.current = null;
|
|
149
168
|
}}
|
|
150
169
|
onDoubleClick={() => {
|
|
151
170
|
setFolded(false);
|
|
152
171
|
set(defaultSize);
|
|
153
172
|
}}
|
|
154
173
|
onKeyDown={(event) => {
|
|
174
|
+
// Escape during a drag puts the panes back as they were.
|
|
175
|
+
if (event.key === "Escape" && drag.current) {
|
|
176
|
+
const { size: before, folded: wasFolded } = drag.current;
|
|
177
|
+
drag.current = null;
|
|
178
|
+
setCurrent(before);
|
|
179
|
+
setFolded(wasFolded);
|
|
180
|
+
event.preventDefault();
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
155
183
|
const step = (event.shiftKey ? 5 : 1) * (units === "pixels" ? 16 : 2);
|
|
156
184
|
const back = horizontal ? "ArrowLeft" : "ArrowUp";
|
|
157
185
|
const forward = horizontal ? "ArrowRight" : "ArrowDown";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import * as React from "react";
|
|
4
|
-
import { clampToStep, percentOf, sliderValueForKey, valueFromRatio } from "@mlola-ui/behavior/logic";
|
|
4
|
+
import { clampToStep, isSidewaysDrag, percentOf, sliderValueForKey, valueFromRatio } from "@mlola-ui/behavior/logic";
|
|
5
5
|
import { cx, useControllableState } from "../_internal/react";
|
|
6
6
|
import { FieldValue, type FormControlProps } from "../input/input";
|
|
7
7
|
|
|
@@ -29,7 +29,9 @@ const Slider = React.forwardRef<HTMLDivElement, SliderProps>(
|
|
|
29
29
|
const [currentRaw, setCurrent] = useControllableState({ value, defaultValue: normalize(defaultValue), onChange: onValueChange });
|
|
30
30
|
const current = normalize(currentRaw);
|
|
31
31
|
const trackRef = React.useRef<HTMLDivElement>(null);
|
|
32
|
-
|
|
32
|
+
// A mouse or pen sets the value where it presses. A finger may be scrolling
|
|
33
|
+
// the page, so it sets the value only once it moves sideways, or on a tap.
|
|
34
|
+
const gesture = React.useRef<{ id: number; touch: boolean; x: number; y: number; active: boolean } | null>(null);
|
|
33
35
|
const generated = React.useId();
|
|
34
36
|
const sliderId = id ?? generated;
|
|
35
37
|
const labelId = label ? `${sliderId}-label` : undefined;
|
|
@@ -69,22 +71,38 @@ const Slider = React.forwardRef<HTMLDivElement, SliderProps>(
|
|
|
69
71
|
event.preventDefault();
|
|
70
72
|
setCurrent(next);
|
|
71
73
|
}}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
dragging.current = true;
|
|
74
|
+
// The whole row takes the pointer, not only the thin track inside it.
|
|
75
|
+
onPointerDown={(event) => {
|
|
76
|
+
if (disabled || event.button !== 0) return;
|
|
77
|
+
const touch = event.pointerType === "touch";
|
|
78
|
+
gesture.current = { id: event.pointerId, touch, x: event.clientX, y: event.clientY, active: !touch };
|
|
79
|
+
if (!touch) {
|
|
79
80
|
event.currentTarget.setPointerCapture(event.pointerId);
|
|
80
81
|
setCurrent(normalize(fromPointer(event.clientX)));
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
82
|
+
}
|
|
83
|
+
}}
|
|
84
|
+
onPointerMove={(event) => {
|
|
85
|
+
const current = gesture.current;
|
|
86
|
+
if (disabled || !current || current.id !== event.pointerId) return;
|
|
87
|
+
if (!current.active) {
|
|
88
|
+
// Sideways is a drag; up or down is the page scrolling, which the browser takes.
|
|
89
|
+
if (!isSidewaysDrag(event.clientX - current.x, event.clientY - current.y)) return;
|
|
90
|
+
current.active = true;
|
|
91
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
92
|
+
}
|
|
93
|
+
setCurrent(normalize(fromPointer(event.clientX)));
|
|
94
|
+
}}
|
|
95
|
+
onPointerUp={(event) => {
|
|
96
|
+
const current = gesture.current;
|
|
97
|
+
gesture.current = null;
|
|
98
|
+
// A tap: the finger set nothing while it could still have been scrolling.
|
|
99
|
+
if (!disabled && current?.touch && !current.active) setCurrent(normalize(fromPointer(event.clientX)));
|
|
100
|
+
}}
|
|
101
|
+
onPointerCancel={() => {
|
|
102
|
+
gesture.current = null;
|
|
103
|
+
}}
|
|
104
|
+
>
|
|
105
|
+
<div ref={trackRef} className="ml-slider-track">
|
|
88
106
|
<span aria-hidden="true" className="ml-slider-range" style={{ width: `${percent}%` }} />
|
|
89
107
|
<span aria-hidden="true" className="ml-slider-thumb" style={{ left: `${percent}%` }} />
|
|
90
108
|
</div>
|
|
@@ -47,12 +47,12 @@
|
|
|
47
47
|
"packages/components/progress/progress.tsx": "sha256-oDxj1Ccl1pKV4+e6A7aaJL1FThW8qs9r4Gb0hEmExeM=",
|
|
48
48
|
"packages/components/radio-group/radio-group.tsx": "sha256-jhnSEBLkdpe8dv5us/Q1sMsQF4sKGRgDXWGKm2JSFew=",
|
|
49
49
|
"packages/components/rating/rating.tsx": "sha256-zgPOQXzAiRE4qGNPQ8qat3SP1XSI/7567kA5VaT51P0=",
|
|
50
|
-
"packages/components/resizable/resizable.tsx": "sha256-
|
|
50
|
+
"packages/components/resizable/resizable.tsx": "sha256-RFBpg/a2O82mmx+O5wT+um+y3y2w0rUMJJdBzRu9ONU=",
|
|
51
51
|
"packages/components/segmented-control/segmented-control.tsx": "sha256-MCBG5XHFWCwbACctsYKbqe8mvSSR6pf60tyRgdCDKDA=",
|
|
52
52
|
"packages/components/select/select.tsx": "sha256-WfS//CI0wnqhsQvglElqPK1MOL5vwjSaBnaC1BpWVVc=",
|
|
53
53
|
"packages/components/sheet/sheet.tsx": "sha256-gmc8rZ87NHfN/bErEWHm6HlaAoeNT/Fw6y2PrW88WFI=",
|
|
54
54
|
"packages/components/skeleton/skeleton.tsx": "sha256-2Fk72NbLr3+CrXH7jGbHNsc3t+vskMqSyySe/UwbGCs=",
|
|
55
|
-
"packages/components/slider/slider.tsx": "sha256-
|
|
55
|
+
"packages/components/slider/slider.tsx": "sha256-o37Xi4J8+d/fhWFf2LdpPluuKDVXECNl4quKTlrqCU4=",
|
|
56
56
|
"packages/components/spinner/spinner.tsx": "sha256-FZQmcGkQ8N0485n9bYsLTpTnolbM729YKjkQrXriz9A=",
|
|
57
57
|
"packages/components/status-icon/labels.ts": "sha256-EE8q+geQBbJUs7I3RmaHZnPwn7Vjk2GjCfxvI4ruXKM=",
|
|
58
58
|
"packages/components/status-icon/status-icon.tsx": "sha256-TtrTeoePyfH1VhKuWC0v12FuwfgND1CHnH5x8fyf4AM=",
|