@yamada-ui/segmented-control 0.4.13 → 0.4.15
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/dist/{chunk-LCPXOL6W.mjs → chunk-DXWQZMEU.mjs} +72 -74
- package/dist/chunk-DXWQZMEU.mjs.map +1 -0
- package/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +71 -73
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/segmented-control.d.mts +6 -1
- package/dist/segmented-control.d.ts +6 -1
- package/dist/segmented-control.js +71 -73
- package/dist/segmented-control.js.map +1 -1
- package/dist/segmented-control.mjs +1 -1
- package/package.json +7 -7
- package/dist/chunk-LCPXOL6W.mjs.map +0 -1
|
@@ -7,10 +7,10 @@ import {
|
|
|
7
7
|
useMultiComponentStyle,
|
|
8
8
|
omitThemeProps
|
|
9
9
|
} from "@yamada-ui/core";
|
|
10
|
+
import { LayoutGroup, Motion } from "@yamada-ui/motion";
|
|
10
11
|
import { useControllableState } from "@yamada-ui/use-controllable-state";
|
|
11
12
|
import { createDescendant } from "@yamada-ui/use-descendant";
|
|
12
13
|
import { trackFocusVisible } from "@yamada-ui/use-focus-visible";
|
|
13
|
-
import { useResizeObserver } from "@yamada-ui/use-resize-observer";
|
|
14
14
|
import {
|
|
15
15
|
ariaAttr,
|
|
16
16
|
createContext,
|
|
@@ -44,48 +44,32 @@ var SegmentedControl = forwardRef(
|
|
|
44
44
|
isDisabled,
|
|
45
45
|
children,
|
|
46
46
|
items = [],
|
|
47
|
+
value,
|
|
48
|
+
defaultValue,
|
|
47
49
|
...rest
|
|
48
50
|
} = omitThemeProps(mergedProps);
|
|
49
|
-
const isMountedRef = useIsMounted();
|
|
50
51
|
id != null ? id : id = useId();
|
|
51
52
|
name != null ? name : name = `segmented-control-${useId()}`;
|
|
52
53
|
rest.onChange = useCallbackRef(rest.onChange);
|
|
53
54
|
const descendants = useDescendants();
|
|
54
55
|
const [focusedIndex, setFocusedIndex] = useState(-1);
|
|
55
56
|
const [isFocusVisible, setIsFocusVisible] = useState(false);
|
|
56
|
-
const [observerRef, containerRect] = useResizeObserver();
|
|
57
57
|
const containerRef = useRef(null);
|
|
58
58
|
const labelRefs = useRef(/* @__PURE__ */ new Map());
|
|
59
|
-
const [
|
|
60
|
-
value
|
|
61
|
-
defaultValue
|
|
59
|
+
const [selectedValue, setSelectedValue] = useControllableState({
|
|
60
|
+
value,
|
|
61
|
+
defaultValue,
|
|
62
62
|
onChange: rest.onChange
|
|
63
63
|
});
|
|
64
|
-
const getActivePosition = useCallback(() => {
|
|
65
|
-
const rect = { width: 0, height: 0, x: 0, y: 0 };
|
|
66
|
-
const el = labelRefs.current.get(value);
|
|
67
|
-
if (!el || !containerRef.current || !observerRef.current)
|
|
68
|
-
return rect;
|
|
69
|
-
const { paddingLeft, paddingTop } = getComputedStyle(containerRef.current);
|
|
70
|
-
const gutterX = parseFloat(paddingLeft) || 0;
|
|
71
|
-
const gutterY = parseFloat(paddingTop) || 0;
|
|
72
|
-
let { width, height } = el.getBoundingClientRect();
|
|
73
|
-
rect.x = el.offsetLeft - gutterX;
|
|
74
|
-
rect.y = el.offsetTop - gutterY;
|
|
75
|
-
rect.width = width * (el.offsetWidth / width) || 0;
|
|
76
|
-
rect.height = height * (el.offsetWidth / width) || 0;
|
|
77
|
-
return rect;
|
|
78
|
-
}, [observerRef, value]);
|
|
79
|
-
const [activePosition, setActivePosition] = useState(getActivePosition);
|
|
80
64
|
const onChange = useCallback(
|
|
81
65
|
(ev) => {
|
|
82
66
|
if (isDisabled || isReadOnly) {
|
|
83
67
|
ev.preventDefault();
|
|
84
68
|
return;
|
|
85
69
|
}
|
|
86
|
-
|
|
70
|
+
setSelectedValue(ev.target.value);
|
|
87
71
|
},
|
|
88
|
-
[isDisabled, isReadOnly,
|
|
72
|
+
[isDisabled, isReadOnly, setSelectedValue]
|
|
89
73
|
);
|
|
90
74
|
const onFocus = useCallback(
|
|
91
75
|
(index, skip) => {
|
|
@@ -104,39 +88,22 @@ var SegmentedControl = forwardRef(
|
|
|
104
88
|
const onBlur = useCallback(() => setFocusedIndex(-1), []);
|
|
105
89
|
const getContainerProps = useCallback(
|
|
106
90
|
(props2 = {}, ref2 = null) => ({
|
|
107
|
-
...omitObject(rest, ["
|
|
91
|
+
...omitObject(rest, ["onChange"]),
|
|
108
92
|
...props2,
|
|
109
|
-
ref: mergeRefs(containerRef,
|
|
93
|
+
ref: mergeRefs(containerRef, ref2),
|
|
110
94
|
id,
|
|
111
95
|
"aria-disabled": ariaAttr(isDisabled),
|
|
112
96
|
"aria-readonly": ariaAttr(isReadOnly),
|
|
113
97
|
onBlur: handlerAll(props2.onBlur, onBlur)
|
|
114
98
|
}),
|
|
115
|
-
[id, isDisabled, isReadOnly,
|
|
116
|
-
);
|
|
117
|
-
const getActiveProps = useCallback(
|
|
118
|
-
(props2 = {}, ref2 = null) => {
|
|
119
|
-
const { width, height, x, y } = activePosition;
|
|
120
|
-
return {
|
|
121
|
-
...props2,
|
|
122
|
-
ref: ref2,
|
|
123
|
-
style: {
|
|
124
|
-
position: "absolute",
|
|
125
|
-
zIndex: 1,
|
|
126
|
-
width,
|
|
127
|
-
height,
|
|
128
|
-
transform: `translate(${x}px, ${y}px)`
|
|
129
|
-
}
|
|
130
|
-
};
|
|
131
|
-
},
|
|
132
|
-
[activePosition]
|
|
99
|
+
[id, isDisabled, isReadOnly, onBlur, rest]
|
|
133
100
|
);
|
|
134
101
|
const getInputProps = useCallback(
|
|
135
102
|
({ index, ...props2 } = {}, ref2 = null) => {
|
|
136
103
|
var _a, _b, _c, _d;
|
|
137
104
|
const disabled = (_b = (_a = props2.disabled) != null ? _a : props2.isDisabled) != null ? _b : isDisabled;
|
|
138
105
|
const readOnly = (_d = (_c = props2.readOnly) != null ? _c : props2.isReadOnly) != null ? _d : isReadOnly;
|
|
139
|
-
const checked = props2.value ===
|
|
106
|
+
const checked = props2.value === selectedValue;
|
|
140
107
|
return {
|
|
141
108
|
...omitObject(props2, ["isDisabled", "isReadOnly"]),
|
|
142
109
|
ref: ref2,
|
|
@@ -167,14 +134,14 @@ var SegmentedControl = forwardRef(
|
|
|
167
134
|
)
|
|
168
135
|
};
|
|
169
136
|
},
|
|
170
|
-
[isDisabled, isReadOnly,
|
|
137
|
+
[isDisabled, isReadOnly, selectedValue, id, name, focusedIndex, onChange]
|
|
171
138
|
);
|
|
172
139
|
const getLabelProps = useCallback(
|
|
173
140
|
({ index, ...props2 } = {}, ref2 = null) => {
|
|
174
141
|
var _a, _b, _c, _d;
|
|
175
142
|
const disabled = (_b = (_a = props2.disabled) != null ? _a : props2.isDisabled) != null ? _b : isDisabled;
|
|
176
143
|
const readOnly = (_d = (_c = props2.readOnly) != null ? _c : props2.isReadOnly) != null ? _d : isReadOnly;
|
|
177
|
-
const checked = props2.value ===
|
|
144
|
+
const checked = props2.value === selectedValue;
|
|
178
145
|
const focused = index === focusedIndex;
|
|
179
146
|
return {
|
|
180
147
|
props: props2,
|
|
@@ -197,18 +164,21 @@ var SegmentedControl = forwardRef(
|
|
|
197
164
|
_focus: {},
|
|
198
165
|
_invalid: {},
|
|
199
166
|
_focusVisible: {}
|
|
200
|
-
} : {}
|
|
201
|
-
style: { position: "relative", zIndex: 2 }
|
|
167
|
+
} : {}
|
|
202
168
|
};
|
|
203
169
|
},
|
|
204
|
-
[
|
|
170
|
+
[
|
|
171
|
+
focusedIndex,
|
|
172
|
+
isDisabled,
|
|
173
|
+
isFocusVisible,
|
|
174
|
+
isReadOnly,
|
|
175
|
+
onFocus,
|
|
176
|
+
selectedValue
|
|
177
|
+
]
|
|
205
178
|
);
|
|
206
179
|
useEffect(() => {
|
|
207
180
|
return trackFocusVisible(setIsFocusVisible);
|
|
208
181
|
}, []);
|
|
209
|
-
useEffect(() => {
|
|
210
|
-
setActivePosition(getActivePosition());
|
|
211
|
-
}, [focusedIndex, containerRect, value, getActivePosition]);
|
|
212
182
|
const css = {
|
|
213
183
|
position: "relative",
|
|
214
184
|
display: "inline-flex",
|
|
@@ -222,38 +192,30 @@ var SegmentedControl = forwardRef(
|
|
|
222
192
|
} else {
|
|
223
193
|
computedChildren = validChildren;
|
|
224
194
|
}
|
|
225
|
-
if (
|
|
195
|
+
if (selectedValue == null && defaultValue == null) {
|
|
226
196
|
for (const child of computedChildren) {
|
|
227
|
-
if (child.type !== SegmentedControlButton)
|
|
228
|
-
|
|
197
|
+
if (child.type !== SegmentedControlButton) {
|
|
198
|
+
if (child.type.displayName !== SegmentedControlButton.displayName)
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
229
201
|
const value2 = child.props.value;
|
|
230
|
-
|
|
202
|
+
setSelectedValue(value2);
|
|
231
203
|
break;
|
|
232
204
|
}
|
|
233
205
|
}
|
|
234
206
|
return /* @__PURE__ */ jsx(DescendantsContextProvider, { value: descendants, children: /* @__PURE__ */ jsx(
|
|
235
207
|
SegmentedControlProvider,
|
|
236
208
|
{
|
|
237
|
-
value: { getInputProps, getLabelProps, styles },
|
|
238
|
-
children: /* @__PURE__ */
|
|
209
|
+
value: { getInputProps, getLabelProps, styles, selectedValue },
|
|
210
|
+
children: /* @__PURE__ */ jsx(LayoutGroup, { id, children: /* @__PURE__ */ jsx(
|
|
239
211
|
ui.div,
|
|
240
212
|
{
|
|
241
213
|
...getContainerProps({}, ref),
|
|
242
214
|
className: cx("ui-segmented-control", className),
|
|
243
215
|
__css: css,
|
|
244
|
-
children:
|
|
245
|
-
isMountedRef.current ? /* @__PURE__ */ jsx(
|
|
246
|
-
ui.span,
|
|
247
|
-
{
|
|
248
|
-
className: "ui-segmented-control__active",
|
|
249
|
-
...getActiveProps(),
|
|
250
|
-
__css: styles.active
|
|
251
|
-
}
|
|
252
|
-
) : null,
|
|
253
|
-
computedChildren
|
|
254
|
-
]
|
|
216
|
+
children: computedChildren
|
|
255
217
|
}
|
|
256
|
-
)
|
|
218
|
+
) })
|
|
257
219
|
}
|
|
258
220
|
) });
|
|
259
221
|
}
|
|
@@ -268,9 +230,11 @@ var SegmentedControlButton = forwardRef(
|
|
|
268
230
|
value,
|
|
269
231
|
onChange,
|
|
270
232
|
children,
|
|
233
|
+
motionProps,
|
|
271
234
|
...rest
|
|
272
235
|
}, ref) => {
|
|
273
|
-
const
|
|
236
|
+
const [, isMounted] = useIsMounted({ rerender: true });
|
|
237
|
+
const { selectedValue, getInputProps, getLabelProps, styles } = useSegmentedControl();
|
|
274
238
|
const { index, register } = useDescendant({
|
|
275
239
|
disabled: isDisabled || isReadOnly
|
|
276
240
|
});
|
|
@@ -284,6 +248,7 @@ var SegmentedControlButton = forwardRef(
|
|
|
284
248
|
isReadOnly
|
|
285
249
|
};
|
|
286
250
|
const css = {
|
|
251
|
+
position: "relative",
|
|
287
252
|
cursor: "pointer",
|
|
288
253
|
flex: "1 1 0%",
|
|
289
254
|
display: "inline-flex",
|
|
@@ -291,6 +256,7 @@ var SegmentedControlButton = forwardRef(
|
|
|
291
256
|
alignItems: "center",
|
|
292
257
|
...styles.button
|
|
293
258
|
};
|
|
259
|
+
const isSelected = selectedValue === value;
|
|
294
260
|
return /* @__PURE__ */ jsxs(
|
|
295
261
|
ui.label,
|
|
296
262
|
{
|
|
@@ -300,15 +266,47 @@ var SegmentedControlButton = forwardRef(
|
|
|
300
266
|
...rest,
|
|
301
267
|
children: [
|
|
302
268
|
/* @__PURE__ */ jsx(ui.input, { ...getInputProps(props, mergeRefs(register, ref)) }),
|
|
303
|
-
/* @__PURE__ */ jsx(ui.span, { children })
|
|
269
|
+
/* @__PURE__ */ jsx(ui.span, { children }),
|
|
270
|
+
isSelected && isMounted ? /* @__PURE__ */ jsx(SegmentedControlCursor, { ...motionProps }) : null
|
|
304
271
|
]
|
|
305
272
|
}
|
|
306
273
|
);
|
|
307
274
|
}
|
|
308
275
|
);
|
|
276
|
+
SegmentedControlButton.displayName = "SegmentedControlButton";
|
|
277
|
+
var SegmentedControlCursor = ({
|
|
278
|
+
className,
|
|
279
|
+
transition,
|
|
280
|
+
...rest
|
|
281
|
+
}) => {
|
|
282
|
+
const { styles } = useSegmentedControl();
|
|
283
|
+
const css = {
|
|
284
|
+
position: "absolute",
|
|
285
|
+
zIndex: "-10",
|
|
286
|
+
w: "full",
|
|
287
|
+
h: "full",
|
|
288
|
+
...styles.cursor
|
|
289
|
+
};
|
|
290
|
+
return /* @__PURE__ */ jsx(
|
|
291
|
+
Motion,
|
|
292
|
+
{
|
|
293
|
+
className: cx("ui-segmented-control__cursor", className),
|
|
294
|
+
layoutDependency: false,
|
|
295
|
+
layoutId: "cursor",
|
|
296
|
+
transition: {
|
|
297
|
+
type: "spring",
|
|
298
|
+
bounce: 0.15,
|
|
299
|
+
duration: 0.4,
|
|
300
|
+
...transition
|
|
301
|
+
},
|
|
302
|
+
__css: css,
|
|
303
|
+
...rest
|
|
304
|
+
}
|
|
305
|
+
);
|
|
306
|
+
};
|
|
309
307
|
|
|
310
308
|
export {
|
|
311
309
|
SegmentedControl,
|
|
312
310
|
SegmentedControlButton
|
|
313
311
|
};
|
|
314
|
-
//# sourceMappingURL=chunk-
|
|
312
|
+
//# sourceMappingURL=chunk-DXWQZMEU.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/segmented-control.tsx"],"sourcesContent":["import type { CSSUIObject, HTMLUIProps, ThemeProps } from \"@yamada-ui/core\"\nimport {\n ui,\n forwardRef,\n useMultiComponentStyle,\n omitThemeProps,\n} from \"@yamada-ui/core\"\nimport type { MotionProps } from \"@yamada-ui/motion\"\nimport { LayoutGroup, Motion } from \"@yamada-ui/motion\"\nimport { useControllableState } from \"@yamada-ui/use-controllable-state\"\nimport { createDescendant } from \"@yamada-ui/use-descendant\"\nimport { trackFocusVisible } from \"@yamada-ui/use-focus-visible\"\nimport type { PropGetter, RequiredPropGetter } from \"@yamada-ui/utils\"\nimport {\n ariaAttr,\n createContext,\n cx,\n dataAttr,\n getValidChildren,\n handlerAll,\n mergeRefs,\n omitObject,\n useCallbackRef,\n useIsMounted,\n} from \"@yamada-ui/utils\"\nimport type { ChangeEvent, ChangeEventHandler, FC, ReactElement } from \"react\"\nimport { useCallback, useEffect, useId, useRef, useState } from \"react\"\n\nexport type SegmentedControlItem = SegmentedControlButtonProps & {\n label?: string\n}\n\nconst { DescendantsContextProvider, useDescendants, useDescendant } =\n createDescendant<HTMLButtonElement>()\n\ntype SegmentedControlContext = {\n selectedValue: string\n getInputProps: RequiredPropGetter<{ index: number }>\n getLabelProps: RequiredPropGetter<{ index: number }>\n styles: Record<string, CSSUIObject>\n}\n\nconst [SegmentedControlProvider, useSegmentedControl] =\n createContext<SegmentedControlContext>({\n strict: false,\n name: \"SegmentedControlContext\",\n })\n\ntype SegmentedControlOptions = {\n /**\n * The HTML `name` attribute used for forms.\n */\n name?: string\n /**\n * The value of the segmented control.\n */\n value?: string\n /**\n * The initial value of the segmented control.\n */\n defaultValue?: string\n /**\n * The callback fired when any children radio is checked or unchecked.\n */\n onChange?: (value: string) => void\n /**\n * If `true`, the segmented control will be readonly.\n *\n * @default false\n */\n isReadOnly?: boolean\n /**\n * If `true`, the segmented control will be disabled.\n *\n * @default false\n */\n isDisabled?: boolean\n /**\n * If provided, generate segmented control buttons but based on items.\n *\n * @default '[]'\n */\n items?: SegmentedControlItem[]\n}\n\nexport type SegmentedControlProps = Omit<\n HTMLUIProps<\"div\">,\n \"value\" | \"defaultValue\" | \"onChange\"\n> &\n ThemeProps<\"SegmentedControl\"> &\n SegmentedControlOptions\n\nexport const SegmentedControl = forwardRef<SegmentedControlProps, \"div\">(\n (props, ref) => {\n const [styles, mergedProps] = useMultiComponentStyle(\n \"SegmentedControl\",\n props,\n )\n let {\n className,\n id,\n name,\n isReadOnly,\n isDisabled,\n children,\n items = [],\n value,\n defaultValue,\n ...rest\n } = omitThemeProps(mergedProps)\n\n id ??= useId()\n name ??= `segmented-control-${useId()}`\n\n rest.onChange = useCallbackRef(rest.onChange)\n\n const descendants = useDescendants()\n\n const [focusedIndex, setFocusedIndex] = useState<number>(-1)\n const [isFocusVisible, setIsFocusVisible] = useState<boolean>(false)\n const containerRef = useRef<HTMLDivElement>(null)\n const labelRefs = useRef<Map<string | number, HTMLLabelElement>>(new Map())\n\n const [selectedValue, setSelectedValue] = useControllableState({\n value,\n defaultValue,\n onChange: rest.onChange,\n })\n\n const onChange = useCallback(\n (ev: ChangeEvent<HTMLInputElement>) => {\n if (isDisabled || isReadOnly) {\n ev.preventDefault()\n\n return\n }\n\n setSelectedValue(ev.target.value)\n },\n [isDisabled, isReadOnly, setSelectedValue],\n )\n\n const onFocus = useCallback(\n (index: number, skip: boolean) => {\n if (isDisabled) return\n\n if (skip) {\n const next = descendants.enabledNextValue(index)\n\n if (next) setFocusedIndex(next.index)\n } else {\n setFocusedIndex(index)\n }\n },\n [descendants, isDisabled],\n )\n\n const onBlur = useCallback(() => setFocusedIndex(-1), [])\n\n const getContainerProps: PropGetter = useCallback(\n (props = {}, ref = null) => ({\n ...omitObject(rest, [\"onChange\"]),\n ...props,\n ref: mergeRefs(containerRef, ref),\n id,\n \"aria-disabled\": ariaAttr(isDisabled),\n \"aria-readonly\": ariaAttr(isReadOnly),\n onBlur: handlerAll(props.onBlur, onBlur),\n }),\n [id, isDisabled, isReadOnly, onBlur, rest],\n )\n\n const getInputProps: RequiredPropGetter<{ index: number }> = useCallback(\n ({ index, ...props } = {}, ref = null) => {\n const disabled = props.disabled ?? props.isDisabled ?? isDisabled\n const readOnly = props.readOnly ?? props.isReadOnly ?? isReadOnly\n const checked = props.value === selectedValue\n\n return {\n ...omitObject(props, [\"isDisabled\", \"isReadOnly\"]),\n ref,\n id: `${id}-${index}`,\n type: \"radio\",\n name,\n disabled: disabled || readOnly,\n readOnly,\n checked,\n \"aria-disabled\": ariaAttr(disabled),\n \"aria-readonly\": ariaAttr(readOnly),\n \"data-checked\": dataAttr(checked),\n \"data-focus\": dataAttr(index === focusedIndex),\n style: {\n border: \"0px\",\n clip: \"rect(0px, 0px, 0px, 0px)\",\n height: \"1px\",\n width: \"1px\",\n margin: \"-1px\",\n padding: \"0px\",\n overflow: \"hidden\",\n whiteSpace: \"nowrap\",\n position: \"absolute\",\n },\n onChange: handlerAll(props.onChange, (ev) =>\n !disabled && !readOnly\n ? onChange(ev as ChangeEvent<HTMLInputElement>)\n : {},\n ),\n }\n },\n [isDisabled, isReadOnly, selectedValue, id, name, focusedIndex, onChange],\n )\n\n const getLabelProps: RequiredPropGetter<{ index: number }> = useCallback(\n ({ index, ...props } = {}, ref = null) => {\n const disabled = props.disabled ?? props.isDisabled ?? isDisabled\n const readOnly = props.readOnly ?? props.isReadOnly ?? isReadOnly\n const checked = props.value === selectedValue\n const focused = index === focusedIndex\n\n return {\n props,\n ref: mergeRefs(\n (node) => labelRefs.current.set(props.value, node),\n ref,\n ),\n \"aria-disabled\": ariaAttr(disabled),\n \"aria-readonly\": ariaAttr(readOnly),\n \"data-checked\": dataAttr(checked),\n \"data-focus\": dataAttr(focused),\n \"data-focus-visible\": dataAttr(focused && isFocusVisible),\n onFocus: handlerAll(props.onFocus, () =>\n onFocus(index, disabled || readOnly),\n ),\n ...(disabled || readOnly\n ? {\n _hover: {},\n _active: {},\n _focus: {},\n _invalid: {},\n _focusVisible: {},\n }\n : {}),\n }\n },\n [\n focusedIndex,\n isDisabled,\n isFocusVisible,\n isReadOnly,\n onFocus,\n selectedValue,\n ],\n )\n\n useEffect(() => {\n return trackFocusVisible(setIsFocusVisible)\n }, [])\n\n const css: CSSUIObject = {\n position: \"relative\",\n display: \"inline-flex\",\n alignItems: \"center\",\n ...styles.container,\n }\n\n const validChildren = getValidChildren(children)\n let computedChildren: ReactElement[] = []\n\n if (!validChildren.length && items.length) {\n computedChildren = items.map(({ label, value, ...props }, i) => (\n <SegmentedControlButton key={i} value={value} {...props}>\n {label}\n </SegmentedControlButton>\n ))\n } else {\n computedChildren = validChildren\n }\n\n if (selectedValue == null && defaultValue == null) {\n for (const child of computedChildren) {\n if (child.type !== SegmentedControlButton)\n if (\n (child.type as any).displayName !==\n SegmentedControlButton.displayName\n )\n continue\n\n const value = child.props.value\n\n setSelectedValue(value)\n\n break\n }\n }\n\n return (\n <DescendantsContextProvider value={descendants}>\n <SegmentedControlProvider\n value={{ getInputProps, getLabelProps, styles, selectedValue }}\n >\n <LayoutGroup id={id}>\n <ui.div\n {...getContainerProps({}, ref)}\n className={cx(\"ui-segmented-control\", className)}\n __css={css}\n >\n {computedChildren}\n </ui.div>\n </LayoutGroup>\n </SegmentedControlProvider>\n </DescendantsContextProvider>\n )\n },\n)\n\ntype SegmentedControlButtonOptions = {\n /**\n * The value of the segmented control button.\n */\n value: string | number\n /**\n * The callback fired when any children radio is checked or unchecked.\n */\n onChange?: ChangeEventHandler<HTMLInputElement>\n /**\n * Props for motion component.\n */\n motionProps?: MotionProps\n}\n\nexport type SegmentedControlButtonProps = Omit<\n HTMLUIProps<\"label\">,\n \"onChange\"\n> &\n Pick<SegmentedControlProps, \"isDisabled\" | \"isReadOnly\"> &\n SegmentedControlButtonOptions\n\nexport const SegmentedControlButton = forwardRef<\n SegmentedControlButtonProps,\n \"input\"\n>(\n (\n {\n className,\n disabled,\n readOnly,\n isDisabled,\n isReadOnly,\n value,\n onChange,\n children,\n motionProps,\n ...rest\n },\n ref,\n ) => {\n const [, isMounted] = useIsMounted({ rerender: true })\n const { selectedValue, getInputProps, getLabelProps, styles } =\n useSegmentedControl()\n\n const { index, register } = useDescendant({\n disabled: isDisabled || isReadOnly,\n })\n\n const props = {\n index,\n value,\n onChange,\n disabled,\n readOnly,\n isDisabled,\n isReadOnly,\n }\n\n const css: CSSUIObject = {\n position: \"relative\",\n cursor: \"pointer\",\n flex: \"1 1 0%\",\n display: \"inline-flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n ...styles.button,\n }\n\n const isSelected = selectedValue === value\n\n return (\n <ui.label\n {...getLabelProps(omitObject(props, [\"onChange\"]))}\n className={cx(\"ui-segmented-control__button\", className)}\n __css={css}\n {...rest}\n >\n <ui.input {...getInputProps(props, mergeRefs(register, ref))} />\n <ui.span>{children}</ui.span>\n {isSelected && isMounted ? (\n <SegmentedControlCursor {...motionProps} />\n ) : null}\n </ui.label>\n )\n },\n)\n\nSegmentedControlButton.displayName = \"SegmentedControlButton\"\n\ntype SegmentedControlCursorProps = MotionProps & { className?: string }\n\nconst SegmentedControlCursor: FC<SegmentedControlCursorProps> = ({\n className,\n transition,\n ...rest\n}) => {\n const { styles } = useSegmentedControl()\n\n const css: CSSUIObject = {\n position: \"absolute\",\n zIndex: \"-10\",\n w: \"full\",\n h: \"full\",\n ...styles.cursor,\n }\n\n return (\n <Motion\n className={cx(\"ui-segmented-control__cursor\", className)}\n layoutDependency={false}\n layoutId=\"cursor\"\n transition={{\n type: \"spring\",\n bounce: 0.15,\n duration: 0.4,\n ...transition,\n }}\n __css={css}\n {...rest}\n />\n )\n}\n"],"mappings":"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","names":["props","ref","value"]}
|
package/dist/index.d.mts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -28,10 +28,10 @@ module.exports = __toCommonJS(src_exports);
|
|
|
28
28
|
|
|
29
29
|
// src/segmented-control.tsx
|
|
30
30
|
var import_core = require("@yamada-ui/core");
|
|
31
|
+
var import_motion = require("@yamada-ui/motion");
|
|
31
32
|
var import_use_controllable_state = require("@yamada-ui/use-controllable-state");
|
|
32
33
|
var import_use_descendant = require("@yamada-ui/use-descendant");
|
|
33
34
|
var import_use_focus_visible = require("@yamada-ui/use-focus-visible");
|
|
34
|
-
var import_use_resize_observer = require("@yamada-ui/use-resize-observer");
|
|
35
35
|
var import_utils = require("@yamada-ui/utils");
|
|
36
36
|
var import_react = require("react");
|
|
37
37
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
@@ -54,48 +54,32 @@ var SegmentedControl = (0, import_core.forwardRef)(
|
|
|
54
54
|
isDisabled,
|
|
55
55
|
children,
|
|
56
56
|
items = [],
|
|
57
|
+
value,
|
|
58
|
+
defaultValue,
|
|
57
59
|
...rest
|
|
58
60
|
} = (0, import_core.omitThemeProps)(mergedProps);
|
|
59
|
-
const isMountedRef = (0, import_utils.useIsMounted)();
|
|
60
61
|
id != null ? id : id = (0, import_react.useId)();
|
|
61
62
|
name != null ? name : name = `segmented-control-${(0, import_react.useId)()}`;
|
|
62
63
|
rest.onChange = (0, import_utils.useCallbackRef)(rest.onChange);
|
|
63
64
|
const descendants = useDescendants();
|
|
64
65
|
const [focusedIndex, setFocusedIndex] = (0, import_react.useState)(-1);
|
|
65
66
|
const [isFocusVisible, setIsFocusVisible] = (0, import_react.useState)(false);
|
|
66
|
-
const [observerRef, containerRect] = (0, import_use_resize_observer.useResizeObserver)();
|
|
67
67
|
const containerRef = (0, import_react.useRef)(null);
|
|
68
68
|
const labelRefs = (0, import_react.useRef)(/* @__PURE__ */ new Map());
|
|
69
|
-
const [
|
|
70
|
-
value
|
|
71
|
-
defaultValue
|
|
69
|
+
const [selectedValue, setSelectedValue] = (0, import_use_controllable_state.useControllableState)({
|
|
70
|
+
value,
|
|
71
|
+
defaultValue,
|
|
72
72
|
onChange: rest.onChange
|
|
73
73
|
});
|
|
74
|
-
const getActivePosition = (0, import_react.useCallback)(() => {
|
|
75
|
-
const rect = { width: 0, height: 0, x: 0, y: 0 };
|
|
76
|
-
const el = labelRefs.current.get(value);
|
|
77
|
-
if (!el || !containerRef.current || !observerRef.current)
|
|
78
|
-
return rect;
|
|
79
|
-
const { paddingLeft, paddingTop } = getComputedStyle(containerRef.current);
|
|
80
|
-
const gutterX = parseFloat(paddingLeft) || 0;
|
|
81
|
-
const gutterY = parseFloat(paddingTop) || 0;
|
|
82
|
-
let { width, height } = el.getBoundingClientRect();
|
|
83
|
-
rect.x = el.offsetLeft - gutterX;
|
|
84
|
-
rect.y = el.offsetTop - gutterY;
|
|
85
|
-
rect.width = width * (el.offsetWidth / width) || 0;
|
|
86
|
-
rect.height = height * (el.offsetWidth / width) || 0;
|
|
87
|
-
return rect;
|
|
88
|
-
}, [observerRef, value]);
|
|
89
|
-
const [activePosition, setActivePosition] = (0, import_react.useState)(getActivePosition);
|
|
90
74
|
const onChange = (0, import_react.useCallback)(
|
|
91
75
|
(ev) => {
|
|
92
76
|
if (isDisabled || isReadOnly) {
|
|
93
77
|
ev.preventDefault();
|
|
94
78
|
return;
|
|
95
79
|
}
|
|
96
|
-
|
|
80
|
+
setSelectedValue(ev.target.value);
|
|
97
81
|
},
|
|
98
|
-
[isDisabled, isReadOnly,
|
|
82
|
+
[isDisabled, isReadOnly, setSelectedValue]
|
|
99
83
|
);
|
|
100
84
|
const onFocus = (0, import_react.useCallback)(
|
|
101
85
|
(index, skip) => {
|
|
@@ -114,39 +98,22 @@ var SegmentedControl = (0, import_core.forwardRef)(
|
|
|
114
98
|
const onBlur = (0, import_react.useCallback)(() => setFocusedIndex(-1), []);
|
|
115
99
|
const getContainerProps = (0, import_react.useCallback)(
|
|
116
100
|
(props2 = {}, ref2 = null) => ({
|
|
117
|
-
...(0, import_utils.omitObject)(rest, ["
|
|
101
|
+
...(0, import_utils.omitObject)(rest, ["onChange"]),
|
|
118
102
|
...props2,
|
|
119
|
-
ref: (0, import_utils.mergeRefs)(containerRef,
|
|
103
|
+
ref: (0, import_utils.mergeRefs)(containerRef, ref2),
|
|
120
104
|
id,
|
|
121
105
|
"aria-disabled": (0, import_utils.ariaAttr)(isDisabled),
|
|
122
106
|
"aria-readonly": (0, import_utils.ariaAttr)(isReadOnly),
|
|
123
107
|
onBlur: (0, import_utils.handlerAll)(props2.onBlur, onBlur)
|
|
124
108
|
}),
|
|
125
|
-
[id, isDisabled, isReadOnly,
|
|
126
|
-
);
|
|
127
|
-
const getActiveProps = (0, import_react.useCallback)(
|
|
128
|
-
(props2 = {}, ref2 = null) => {
|
|
129
|
-
const { width, height, x, y } = activePosition;
|
|
130
|
-
return {
|
|
131
|
-
...props2,
|
|
132
|
-
ref: ref2,
|
|
133
|
-
style: {
|
|
134
|
-
position: "absolute",
|
|
135
|
-
zIndex: 1,
|
|
136
|
-
width,
|
|
137
|
-
height,
|
|
138
|
-
transform: `translate(${x}px, ${y}px)`
|
|
139
|
-
}
|
|
140
|
-
};
|
|
141
|
-
},
|
|
142
|
-
[activePosition]
|
|
109
|
+
[id, isDisabled, isReadOnly, onBlur, rest]
|
|
143
110
|
);
|
|
144
111
|
const getInputProps = (0, import_react.useCallback)(
|
|
145
112
|
({ index, ...props2 } = {}, ref2 = null) => {
|
|
146
113
|
var _a, _b, _c, _d;
|
|
147
114
|
const disabled = (_b = (_a = props2.disabled) != null ? _a : props2.isDisabled) != null ? _b : isDisabled;
|
|
148
115
|
const readOnly = (_d = (_c = props2.readOnly) != null ? _c : props2.isReadOnly) != null ? _d : isReadOnly;
|
|
149
|
-
const checked = props2.value ===
|
|
116
|
+
const checked = props2.value === selectedValue;
|
|
150
117
|
return {
|
|
151
118
|
...(0, import_utils.omitObject)(props2, ["isDisabled", "isReadOnly"]),
|
|
152
119
|
ref: ref2,
|
|
@@ -177,14 +144,14 @@ var SegmentedControl = (0, import_core.forwardRef)(
|
|
|
177
144
|
)
|
|
178
145
|
};
|
|
179
146
|
},
|
|
180
|
-
[isDisabled, isReadOnly,
|
|
147
|
+
[isDisabled, isReadOnly, selectedValue, id, name, focusedIndex, onChange]
|
|
181
148
|
);
|
|
182
149
|
const getLabelProps = (0, import_react.useCallback)(
|
|
183
150
|
({ index, ...props2 } = {}, ref2 = null) => {
|
|
184
151
|
var _a, _b, _c, _d;
|
|
185
152
|
const disabled = (_b = (_a = props2.disabled) != null ? _a : props2.isDisabled) != null ? _b : isDisabled;
|
|
186
153
|
const readOnly = (_d = (_c = props2.readOnly) != null ? _c : props2.isReadOnly) != null ? _d : isReadOnly;
|
|
187
|
-
const checked = props2.value ===
|
|
154
|
+
const checked = props2.value === selectedValue;
|
|
188
155
|
const focused = index === focusedIndex;
|
|
189
156
|
return {
|
|
190
157
|
props: props2,
|
|
@@ -207,18 +174,21 @@ var SegmentedControl = (0, import_core.forwardRef)(
|
|
|
207
174
|
_focus: {},
|
|
208
175
|
_invalid: {},
|
|
209
176
|
_focusVisible: {}
|
|
210
|
-
} : {}
|
|
211
|
-
style: { position: "relative", zIndex: 2 }
|
|
177
|
+
} : {}
|
|
212
178
|
};
|
|
213
179
|
},
|
|
214
|
-
[
|
|
180
|
+
[
|
|
181
|
+
focusedIndex,
|
|
182
|
+
isDisabled,
|
|
183
|
+
isFocusVisible,
|
|
184
|
+
isReadOnly,
|
|
185
|
+
onFocus,
|
|
186
|
+
selectedValue
|
|
187
|
+
]
|
|
215
188
|
);
|
|
216
189
|
(0, import_react.useEffect)(() => {
|
|
217
190
|
return (0, import_use_focus_visible.trackFocusVisible)(setIsFocusVisible);
|
|
218
191
|
}, []);
|
|
219
|
-
(0, import_react.useEffect)(() => {
|
|
220
|
-
setActivePosition(getActivePosition());
|
|
221
|
-
}, [focusedIndex, containerRect, value, getActivePosition]);
|
|
222
192
|
const css = {
|
|
223
193
|
position: "relative",
|
|
224
194
|
display: "inline-flex",
|
|
@@ -232,38 +202,30 @@ var SegmentedControl = (0, import_core.forwardRef)(
|
|
|
232
202
|
} else {
|
|
233
203
|
computedChildren = validChildren;
|
|
234
204
|
}
|
|
235
|
-
if (
|
|
205
|
+
if (selectedValue == null && defaultValue == null) {
|
|
236
206
|
for (const child of computedChildren) {
|
|
237
|
-
if (child.type !== SegmentedControlButton)
|
|
238
|
-
|
|
207
|
+
if (child.type !== SegmentedControlButton) {
|
|
208
|
+
if (child.type.displayName !== SegmentedControlButton.displayName)
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
239
211
|
const value2 = child.props.value;
|
|
240
|
-
|
|
212
|
+
setSelectedValue(value2);
|
|
241
213
|
break;
|
|
242
214
|
}
|
|
243
215
|
}
|
|
244
216
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DescendantsContextProvider, { value: descendants, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
245
217
|
SegmentedControlProvider,
|
|
246
218
|
{
|
|
247
|
-
value: { getInputProps, getLabelProps, styles },
|
|
248
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.
|
|
219
|
+
value: { getInputProps, getLabelProps, styles, selectedValue },
|
|
220
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_motion.LayoutGroup, { id, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
249
221
|
import_core.ui.div,
|
|
250
222
|
{
|
|
251
223
|
...getContainerProps({}, ref),
|
|
252
224
|
className: (0, import_utils.cx)("ui-segmented-control", className),
|
|
253
225
|
__css: css,
|
|
254
|
-
children:
|
|
255
|
-
isMountedRef.current ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
256
|
-
import_core.ui.span,
|
|
257
|
-
{
|
|
258
|
-
className: "ui-segmented-control__active",
|
|
259
|
-
...getActiveProps(),
|
|
260
|
-
__css: styles.active
|
|
261
|
-
}
|
|
262
|
-
) : null,
|
|
263
|
-
computedChildren
|
|
264
|
-
]
|
|
226
|
+
children: computedChildren
|
|
265
227
|
}
|
|
266
|
-
)
|
|
228
|
+
) })
|
|
267
229
|
}
|
|
268
230
|
) });
|
|
269
231
|
}
|
|
@@ -278,9 +240,11 @@ var SegmentedControlButton = (0, import_core.forwardRef)(
|
|
|
278
240
|
value,
|
|
279
241
|
onChange,
|
|
280
242
|
children,
|
|
243
|
+
motionProps,
|
|
281
244
|
...rest
|
|
282
245
|
}, ref) => {
|
|
283
|
-
const
|
|
246
|
+
const [, isMounted] = (0, import_utils.useIsMounted)({ rerender: true });
|
|
247
|
+
const { selectedValue, getInputProps, getLabelProps, styles } = useSegmentedControl();
|
|
284
248
|
const { index, register } = useDescendant({
|
|
285
249
|
disabled: isDisabled || isReadOnly
|
|
286
250
|
});
|
|
@@ -294,6 +258,7 @@ var SegmentedControlButton = (0, import_core.forwardRef)(
|
|
|
294
258
|
isReadOnly
|
|
295
259
|
};
|
|
296
260
|
const css = {
|
|
261
|
+
position: "relative",
|
|
297
262
|
cursor: "pointer",
|
|
298
263
|
flex: "1 1 0%",
|
|
299
264
|
display: "inline-flex",
|
|
@@ -301,6 +266,7 @@ var SegmentedControlButton = (0, import_core.forwardRef)(
|
|
|
301
266
|
alignItems: "center",
|
|
302
267
|
...styles.button
|
|
303
268
|
};
|
|
269
|
+
const isSelected = selectedValue === value;
|
|
304
270
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
305
271
|
import_core.ui.label,
|
|
306
272
|
{
|
|
@@ -310,12 +276,44 @@ var SegmentedControlButton = (0, import_core.forwardRef)(
|
|
|
310
276
|
...rest,
|
|
311
277
|
children: [
|
|
312
278
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.ui.input, { ...getInputProps(props, (0, import_utils.mergeRefs)(register, ref)) }),
|
|
313
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.ui.span, { children })
|
|
279
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.ui.span, { children }),
|
|
280
|
+
isSelected && isMounted ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SegmentedControlCursor, { ...motionProps }) : null
|
|
314
281
|
]
|
|
315
282
|
}
|
|
316
283
|
);
|
|
317
284
|
}
|
|
318
285
|
);
|
|
286
|
+
SegmentedControlButton.displayName = "SegmentedControlButton";
|
|
287
|
+
var SegmentedControlCursor = ({
|
|
288
|
+
className,
|
|
289
|
+
transition,
|
|
290
|
+
...rest
|
|
291
|
+
}) => {
|
|
292
|
+
const { styles } = useSegmentedControl();
|
|
293
|
+
const css = {
|
|
294
|
+
position: "absolute",
|
|
295
|
+
zIndex: "-10",
|
|
296
|
+
w: "full",
|
|
297
|
+
h: "full",
|
|
298
|
+
...styles.cursor
|
|
299
|
+
};
|
|
300
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
301
|
+
import_motion.Motion,
|
|
302
|
+
{
|
|
303
|
+
className: (0, import_utils.cx)("ui-segmented-control__cursor", className),
|
|
304
|
+
layoutDependency: false,
|
|
305
|
+
layoutId: "cursor",
|
|
306
|
+
transition: {
|
|
307
|
+
type: "spring",
|
|
308
|
+
bounce: 0.15,
|
|
309
|
+
duration: 0.4,
|
|
310
|
+
...transition
|
|
311
|
+
},
|
|
312
|
+
__css: css,
|
|
313
|
+
...rest
|
|
314
|
+
}
|
|
315
|
+
);
|
|
316
|
+
};
|
|
319
317
|
// Annotate the CommonJS export names for ESM import in node:
|
|
320
318
|
0 && (module.exports = {
|
|
321
319
|
SegmentedControl,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/segmented-control.tsx"],"sourcesContent":["export { SegmentedControl, SegmentedControlButton } from \"./segmented-control\"\nexport type {\n SegmentedControlItem,\n SegmentedControlProps,\n SegmentedControlButtonProps,\n} from \"./segmented-control\"\n","import type { CSSUIObject, HTMLUIProps, ThemeProps } from \"@yamada-ui/core\"\nimport {\n ui,\n forwardRef,\n useMultiComponentStyle,\n omitThemeProps,\n} from \"@yamada-ui/core\"\nimport { useControllableState } from \"@yamada-ui/use-controllable-state\"\nimport { createDescendant } from \"@yamada-ui/use-descendant\"\nimport { trackFocusVisible } from \"@yamada-ui/use-focus-visible\"\nimport { useResizeObserver } from \"@yamada-ui/use-resize-observer\"\nimport type { PropGetter, RequiredPropGetter } from \"@yamada-ui/utils\"\nimport {\n ariaAttr,\n createContext,\n cx,\n dataAttr,\n getValidChildren,\n handlerAll,\n mergeRefs,\n omitObject,\n useCallbackRef,\n useIsMounted,\n} from \"@yamada-ui/utils\"\nimport type { ChangeEvent, ChangeEventHandler, ReactElement } from \"react\"\nimport { useCallback, useEffect, useId, useRef, useState } from \"react\"\n\nexport type SegmentedControlItem = SegmentedControlButtonProps & {\n label?: string\n}\n\nconst { DescendantsContextProvider, useDescendants, useDescendant } =\n createDescendant<HTMLButtonElement>()\n\ntype SegmentedControlContext = {\n getInputProps: RequiredPropGetter<{ index: number }>\n getLabelProps: RequiredPropGetter<{ index: number }>\n styles: Record<string, CSSUIObject>\n}\n\nconst [SegmentedControlProvider, useSegmentedControl] =\n createContext<SegmentedControlContext>({\n strict: false,\n name: \"SegmentedControlContext\",\n })\n\ntype SegmentedControlOptions = {\n /**\n * The HTML `name` attribute used for forms.\n */\n name?: string\n /**\n * The value of the segmented control.\n */\n value?: string\n /**\n * The initial value of the segmented control.\n */\n defaultValue?: string\n /**\n * The callback fired when any children radio is checked or unchecked.\n */\n onChange?: (value: string) => void\n /**\n * If `true`, the segmented control will be readonly.\n *\n * @default false\n */\n isReadOnly?: boolean\n /**\n * If `true`, the segmented control will be disabled.\n *\n * @default false\n */\n isDisabled?: boolean\n /**\n * If provided, generate segmented control buttons but based on items.\n *\n * @default '[]'\n */\n items?: SegmentedControlItem[]\n}\n\nexport type SegmentedControlProps = Omit<HTMLUIProps<\"div\">, \"onChange\"> &\n ThemeProps<\"SegmentedControl\"> &\n SegmentedControlOptions\n\nexport const SegmentedControl = forwardRef<SegmentedControlProps, \"div\">(\n (props, ref) => {\n const [styles, mergedProps] = useMultiComponentStyle(\n \"SegmentedControl\",\n props,\n )\n let {\n className,\n id,\n name,\n isReadOnly,\n isDisabled,\n children,\n items = [],\n ...rest\n } = omitThemeProps(mergedProps)\n const isMountedRef = useIsMounted()\n\n id ??= useId()\n name ??= `segmented-control-${useId()}`\n\n rest.onChange = useCallbackRef(rest.onChange)\n\n const descendants = useDescendants()\n\n const [focusedIndex, setFocusedIndex] = useState<number>(-1)\n const [isFocusVisible, setIsFocusVisible] = useState<boolean>(false)\n const [observerRef, containerRect] = useResizeObserver()\n const containerRef = useRef<HTMLDivElement>(null)\n const labelRefs = useRef<Map<string | number, HTMLLabelElement>>(new Map())\n\n const [value, setValue] = useControllableState({\n value: rest.value,\n defaultValue: rest.defaultValue,\n onChange: rest.onChange,\n })\n\n const getActivePosition = useCallback(() => {\n const rect = { width: 0, height: 0, x: 0, y: 0 }\n\n const el = labelRefs.current.get(value)\n\n if (!el || !containerRef.current || !observerRef.current) return rect\n\n const { paddingLeft, paddingTop } = getComputedStyle(containerRef.current)\n\n const gutterX = parseFloat(paddingLeft) || 0\n const gutterY = parseFloat(paddingTop) || 0\n\n let { width, height } = el.getBoundingClientRect()\n rect.x = el.offsetLeft - gutterX\n rect.y = el.offsetTop - gutterY\n\n rect.width = width * (el.offsetWidth / width) || 0\n rect.height = height * (el.offsetWidth / width) || 0\n\n return rect\n }, [observerRef, value])\n\n const [activePosition, setActivePosition] = useState(getActivePosition)\n\n const onChange = useCallback(\n (ev: ChangeEvent<HTMLInputElement>) => {\n if (isDisabled || isReadOnly) {\n ev.preventDefault()\n\n return\n }\n\n setValue(ev.target.value)\n },\n [isDisabled, isReadOnly, setValue],\n )\n\n const onFocus = useCallback(\n (index: number, skip: boolean) => {\n if (isDisabled) return\n\n if (skip) {\n const next = descendants.enabledNextValue(index)\n\n if (next) setFocusedIndex(next.index)\n } else {\n setFocusedIndex(index)\n }\n },\n [descendants, isDisabled],\n )\n\n const onBlur = useCallback(() => setFocusedIndex(-1), [])\n\n const getContainerProps: PropGetter = useCallback(\n (props = {}, ref = null) => ({\n ...omitObject(rest, [\"value\", \"defaultValue\", \"onChange\"]),\n ...props,\n ref: mergeRefs(containerRef, observerRef, ref),\n id,\n \"aria-disabled\": ariaAttr(isDisabled),\n \"aria-readonly\": ariaAttr(isReadOnly),\n onBlur: handlerAll(props.onBlur, onBlur),\n }),\n [id, isDisabled, isReadOnly, observerRef, onBlur, rest],\n )\n\n const getActiveProps: PropGetter = useCallback(\n (props = {}, ref = null) => {\n const { width, height, x, y } = activePosition\n\n return {\n ...props,\n ref,\n style: {\n position: \"absolute\",\n zIndex: 1,\n width,\n height,\n transform: `translate(${x}px, ${y}px)`,\n },\n }\n },\n [activePosition],\n )\n\n const getInputProps: RequiredPropGetter<{ index: number }> = useCallback(\n ({ index, ...props } = {}, ref = null) => {\n const disabled = props.disabled ?? props.isDisabled ?? isDisabled\n const readOnly = props.readOnly ?? props.isReadOnly ?? isReadOnly\n const checked = props.value === value\n\n return {\n ...omitObject(props, [\"isDisabled\", \"isReadOnly\"]),\n ref,\n id: `${id}-${index}`,\n type: \"radio\",\n name,\n disabled: disabled || readOnly,\n readOnly,\n checked,\n \"aria-disabled\": ariaAttr(disabled),\n \"aria-readonly\": ariaAttr(readOnly),\n \"data-checked\": dataAttr(checked),\n \"data-focus\": dataAttr(index === focusedIndex),\n style: {\n border: \"0px\",\n clip: \"rect(0px, 0px, 0px, 0px)\",\n height: \"1px\",\n width: \"1px\",\n margin: \"-1px\",\n padding: \"0px\",\n overflow: \"hidden\",\n whiteSpace: \"nowrap\",\n position: \"absolute\",\n },\n onChange: handlerAll(props.onChange, (ev) =>\n !disabled && !readOnly\n ? onChange(ev as ChangeEvent<HTMLInputElement>)\n : {},\n ),\n }\n },\n [isDisabled, isReadOnly, value, id, name, focusedIndex, onChange],\n )\n\n const getLabelProps: RequiredPropGetter<{ index: number }> = useCallback(\n ({ index, ...props } = {}, ref = null) => {\n const disabled = props.disabled ?? props.isDisabled ?? isDisabled\n const readOnly = props.readOnly ?? props.isReadOnly ?? isReadOnly\n const checked = props.value === value\n const focused = index === focusedIndex\n\n return {\n props,\n ref: mergeRefs(\n (node) => labelRefs.current.set(props.value, node),\n ref,\n ),\n \"aria-disabled\": ariaAttr(disabled),\n \"aria-readonly\": ariaAttr(readOnly),\n \"data-checked\": dataAttr(checked),\n \"data-focus\": dataAttr(focused),\n \"data-focus-visible\": dataAttr(focused && isFocusVisible),\n onFocus: handlerAll(props.onFocus, () =>\n onFocus(index, disabled || readOnly),\n ),\n ...(disabled || readOnly\n ? {\n _hover: {},\n _active: {},\n _focus: {},\n _invalid: {},\n _focusVisible: {},\n }\n : {}),\n style: { position: \"relative\", zIndex: 2 },\n }\n },\n [focusedIndex, isDisabled, isFocusVisible, isReadOnly, onFocus, value],\n )\n\n useEffect(() => {\n return trackFocusVisible(setIsFocusVisible)\n }, [])\n\n useEffect(() => {\n setActivePosition(getActivePosition())\n }, [focusedIndex, containerRect, value, getActivePosition])\n\n const css: CSSUIObject = {\n position: \"relative\",\n display: \"inline-flex\",\n alignItems: \"center\",\n ...styles.container,\n }\n\n const validChildren = getValidChildren(children)\n let computedChildren: ReactElement[] = []\n\n if (!validChildren.length && items.length) {\n computedChildren = items.map(({ label, value, ...props }, i) => (\n <SegmentedControlButton key={i} value={value} {...props}>\n {label}\n </SegmentedControlButton>\n ))\n } else {\n computedChildren = validChildren\n }\n\n if (value == null && rest.defaultValue == null) {\n for (const child of computedChildren) {\n if (child.type !== SegmentedControlButton) continue\n\n const value = child.props.value\n\n setValue(value)\n\n break\n }\n }\n\n return (\n <DescendantsContextProvider value={descendants}>\n <SegmentedControlProvider\n value={{ getInputProps, getLabelProps, styles }}\n >\n <ui.div\n {...getContainerProps({}, ref)}\n className={cx(\"ui-segmented-control\", className)}\n __css={css}\n >\n {isMountedRef.current ? (\n <ui.span\n className=\"ui-segmented-control__active\"\n {...getActiveProps()}\n __css={styles.active}\n />\n ) : null}\n\n {computedChildren}\n </ui.div>\n </SegmentedControlProvider>\n </DescendantsContextProvider>\n )\n },\n)\n\ntype SegmentedControlButtonOptions = {\n /**\n * The value of the segmented control button.\n */\n value: string | number\n /**\n * The callback fired when any children radio is checked or unchecked.\n */\n onChange?: ChangeEventHandler<HTMLInputElement>\n}\n\nexport type SegmentedControlButtonProps = Omit<\n HTMLUIProps<\"label\">,\n \"onChange\"\n> &\n Pick<SegmentedControlProps, \"isDisabled\" | \"isReadOnly\"> &\n SegmentedControlButtonOptions\n\nexport const SegmentedControlButton = forwardRef<\n SegmentedControlButtonProps,\n \"input\"\n>(\n (\n {\n className,\n disabled,\n readOnly,\n isDisabled,\n isReadOnly,\n value,\n onChange,\n children,\n ...rest\n },\n ref,\n ) => {\n const { getInputProps, getLabelProps, styles } = useSegmentedControl()\n\n const { index, register } = useDescendant({\n disabled: isDisabled || isReadOnly,\n })\n\n const props = {\n index,\n value,\n onChange,\n disabled,\n readOnly,\n isDisabled,\n isReadOnly,\n }\n\n const css: CSSUIObject = {\n cursor: \"pointer\",\n flex: \"1 1 0%\",\n display: \"inline-flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n ...styles.button,\n }\n\n return (\n <ui.label\n {...getLabelProps(omitObject(props, [\"onChange\"]))}\n className={cx(\"ui-segmented-control__button\", className)}\n __css={css}\n {...rest}\n >\n <ui.input {...getInputProps(props, mergeRefs(register, ref))} />\n <ui.span>{children}</ui.span>\n </ui.label>\n )\n },\n)\n"],"mappings":"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","names":["props","ref","value"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/segmented-control.tsx"],"sourcesContent":["export { SegmentedControl, SegmentedControlButton } from \"./segmented-control\"\nexport type {\n SegmentedControlItem,\n SegmentedControlProps,\n SegmentedControlButtonProps,\n} from \"./segmented-control\"\n","import type { CSSUIObject, HTMLUIProps, ThemeProps } from \"@yamada-ui/core\"\nimport {\n ui,\n forwardRef,\n useMultiComponentStyle,\n omitThemeProps,\n} from \"@yamada-ui/core\"\nimport type { MotionProps } from \"@yamada-ui/motion\"\nimport { LayoutGroup, Motion } from \"@yamada-ui/motion\"\nimport { useControllableState } from \"@yamada-ui/use-controllable-state\"\nimport { createDescendant } from \"@yamada-ui/use-descendant\"\nimport { trackFocusVisible } from \"@yamada-ui/use-focus-visible\"\nimport type { PropGetter, RequiredPropGetter } from \"@yamada-ui/utils\"\nimport {\n ariaAttr,\n createContext,\n cx,\n dataAttr,\n getValidChildren,\n handlerAll,\n mergeRefs,\n omitObject,\n useCallbackRef,\n useIsMounted,\n} from \"@yamada-ui/utils\"\nimport type { ChangeEvent, ChangeEventHandler, FC, ReactElement } from \"react\"\nimport { useCallback, useEffect, useId, useRef, useState } from \"react\"\n\nexport type SegmentedControlItem = SegmentedControlButtonProps & {\n label?: string\n}\n\nconst { DescendantsContextProvider, useDescendants, useDescendant } =\n createDescendant<HTMLButtonElement>()\n\ntype SegmentedControlContext = {\n selectedValue: string\n getInputProps: RequiredPropGetter<{ index: number }>\n getLabelProps: RequiredPropGetter<{ index: number }>\n styles: Record<string, CSSUIObject>\n}\n\nconst [SegmentedControlProvider, useSegmentedControl] =\n createContext<SegmentedControlContext>({\n strict: false,\n name: \"SegmentedControlContext\",\n })\n\ntype SegmentedControlOptions = {\n /**\n * The HTML `name` attribute used for forms.\n */\n name?: string\n /**\n * The value of the segmented control.\n */\n value?: string\n /**\n * The initial value of the segmented control.\n */\n defaultValue?: string\n /**\n * The callback fired when any children radio is checked or unchecked.\n */\n onChange?: (value: string) => void\n /**\n * If `true`, the segmented control will be readonly.\n *\n * @default false\n */\n isReadOnly?: boolean\n /**\n * If `true`, the segmented control will be disabled.\n *\n * @default false\n */\n isDisabled?: boolean\n /**\n * If provided, generate segmented control buttons but based on items.\n *\n * @default '[]'\n */\n items?: SegmentedControlItem[]\n}\n\nexport type SegmentedControlProps = Omit<\n HTMLUIProps<\"div\">,\n \"value\" | \"defaultValue\" | \"onChange\"\n> &\n ThemeProps<\"SegmentedControl\"> &\n SegmentedControlOptions\n\nexport const SegmentedControl = forwardRef<SegmentedControlProps, \"div\">(\n (props, ref) => {\n const [styles, mergedProps] = useMultiComponentStyle(\n \"SegmentedControl\",\n props,\n )\n let {\n className,\n id,\n name,\n isReadOnly,\n isDisabled,\n children,\n items = [],\n value,\n defaultValue,\n ...rest\n } = omitThemeProps(mergedProps)\n\n id ??= useId()\n name ??= `segmented-control-${useId()}`\n\n rest.onChange = useCallbackRef(rest.onChange)\n\n const descendants = useDescendants()\n\n const [focusedIndex, setFocusedIndex] = useState<number>(-1)\n const [isFocusVisible, setIsFocusVisible] = useState<boolean>(false)\n const containerRef = useRef<HTMLDivElement>(null)\n const labelRefs = useRef<Map<string | number, HTMLLabelElement>>(new Map())\n\n const [selectedValue, setSelectedValue] = useControllableState({\n value,\n defaultValue,\n onChange: rest.onChange,\n })\n\n const onChange = useCallback(\n (ev: ChangeEvent<HTMLInputElement>) => {\n if (isDisabled || isReadOnly) {\n ev.preventDefault()\n\n return\n }\n\n setSelectedValue(ev.target.value)\n },\n [isDisabled, isReadOnly, setSelectedValue],\n )\n\n const onFocus = useCallback(\n (index: number, skip: boolean) => {\n if (isDisabled) return\n\n if (skip) {\n const next = descendants.enabledNextValue(index)\n\n if (next) setFocusedIndex(next.index)\n } else {\n setFocusedIndex(index)\n }\n },\n [descendants, isDisabled],\n )\n\n const onBlur = useCallback(() => setFocusedIndex(-1), [])\n\n const getContainerProps: PropGetter = useCallback(\n (props = {}, ref = null) => ({\n ...omitObject(rest, [\"onChange\"]),\n ...props,\n ref: mergeRefs(containerRef, ref),\n id,\n \"aria-disabled\": ariaAttr(isDisabled),\n \"aria-readonly\": ariaAttr(isReadOnly),\n onBlur: handlerAll(props.onBlur, onBlur),\n }),\n [id, isDisabled, isReadOnly, onBlur, rest],\n )\n\n const getInputProps: RequiredPropGetter<{ index: number }> = useCallback(\n ({ index, ...props } = {}, ref = null) => {\n const disabled = props.disabled ?? props.isDisabled ?? isDisabled\n const readOnly = props.readOnly ?? props.isReadOnly ?? isReadOnly\n const checked = props.value === selectedValue\n\n return {\n ...omitObject(props, [\"isDisabled\", \"isReadOnly\"]),\n ref,\n id: `${id}-${index}`,\n type: \"radio\",\n name,\n disabled: disabled || readOnly,\n readOnly,\n checked,\n \"aria-disabled\": ariaAttr(disabled),\n \"aria-readonly\": ariaAttr(readOnly),\n \"data-checked\": dataAttr(checked),\n \"data-focus\": dataAttr(index === focusedIndex),\n style: {\n border: \"0px\",\n clip: \"rect(0px, 0px, 0px, 0px)\",\n height: \"1px\",\n width: \"1px\",\n margin: \"-1px\",\n padding: \"0px\",\n overflow: \"hidden\",\n whiteSpace: \"nowrap\",\n position: \"absolute\",\n },\n onChange: handlerAll(props.onChange, (ev) =>\n !disabled && !readOnly\n ? onChange(ev as ChangeEvent<HTMLInputElement>)\n : {},\n ),\n }\n },\n [isDisabled, isReadOnly, selectedValue, id, name, focusedIndex, onChange],\n )\n\n const getLabelProps: RequiredPropGetter<{ index: number }> = useCallback(\n ({ index, ...props } = {}, ref = null) => {\n const disabled = props.disabled ?? props.isDisabled ?? isDisabled\n const readOnly = props.readOnly ?? props.isReadOnly ?? isReadOnly\n const checked = props.value === selectedValue\n const focused = index === focusedIndex\n\n return {\n props,\n ref: mergeRefs(\n (node) => labelRefs.current.set(props.value, node),\n ref,\n ),\n \"aria-disabled\": ariaAttr(disabled),\n \"aria-readonly\": ariaAttr(readOnly),\n \"data-checked\": dataAttr(checked),\n \"data-focus\": dataAttr(focused),\n \"data-focus-visible\": dataAttr(focused && isFocusVisible),\n onFocus: handlerAll(props.onFocus, () =>\n onFocus(index, disabled || readOnly),\n ),\n ...(disabled || readOnly\n ? {\n _hover: {},\n _active: {},\n _focus: {},\n _invalid: {},\n _focusVisible: {},\n }\n : {}),\n }\n },\n [\n focusedIndex,\n isDisabled,\n isFocusVisible,\n isReadOnly,\n onFocus,\n selectedValue,\n ],\n )\n\n useEffect(() => {\n return trackFocusVisible(setIsFocusVisible)\n }, [])\n\n const css: CSSUIObject = {\n position: \"relative\",\n display: \"inline-flex\",\n alignItems: \"center\",\n ...styles.container,\n }\n\n const validChildren = getValidChildren(children)\n let computedChildren: ReactElement[] = []\n\n if (!validChildren.length && items.length) {\n computedChildren = items.map(({ label, value, ...props }, i) => (\n <SegmentedControlButton key={i} value={value} {...props}>\n {label}\n </SegmentedControlButton>\n ))\n } else {\n computedChildren = validChildren\n }\n\n if (selectedValue == null && defaultValue == null) {\n for (const child of computedChildren) {\n if (child.type !== SegmentedControlButton)\n if (\n (child.type as any).displayName !==\n SegmentedControlButton.displayName\n )\n continue\n\n const value = child.props.value\n\n setSelectedValue(value)\n\n break\n }\n }\n\n return (\n <DescendantsContextProvider value={descendants}>\n <SegmentedControlProvider\n value={{ getInputProps, getLabelProps, styles, selectedValue }}\n >\n <LayoutGroup id={id}>\n <ui.div\n {...getContainerProps({}, ref)}\n className={cx(\"ui-segmented-control\", className)}\n __css={css}\n >\n {computedChildren}\n </ui.div>\n </LayoutGroup>\n </SegmentedControlProvider>\n </DescendantsContextProvider>\n )\n },\n)\n\ntype SegmentedControlButtonOptions = {\n /**\n * The value of the segmented control button.\n */\n value: string | number\n /**\n * The callback fired when any children radio is checked or unchecked.\n */\n onChange?: ChangeEventHandler<HTMLInputElement>\n /**\n * Props for motion component.\n */\n motionProps?: MotionProps\n}\n\nexport type SegmentedControlButtonProps = Omit<\n HTMLUIProps<\"label\">,\n \"onChange\"\n> &\n Pick<SegmentedControlProps, \"isDisabled\" | \"isReadOnly\"> &\n SegmentedControlButtonOptions\n\nexport const SegmentedControlButton = forwardRef<\n SegmentedControlButtonProps,\n \"input\"\n>(\n (\n {\n className,\n disabled,\n readOnly,\n isDisabled,\n isReadOnly,\n value,\n onChange,\n children,\n motionProps,\n ...rest\n },\n ref,\n ) => {\n const [, isMounted] = useIsMounted({ rerender: true })\n const { selectedValue, getInputProps, getLabelProps, styles } =\n useSegmentedControl()\n\n const { index, register } = useDescendant({\n disabled: isDisabled || isReadOnly,\n })\n\n const props = {\n index,\n value,\n onChange,\n disabled,\n readOnly,\n isDisabled,\n isReadOnly,\n }\n\n const css: CSSUIObject = {\n position: \"relative\",\n cursor: \"pointer\",\n flex: \"1 1 0%\",\n display: \"inline-flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n ...styles.button,\n }\n\n const isSelected = selectedValue === value\n\n return (\n <ui.label\n {...getLabelProps(omitObject(props, [\"onChange\"]))}\n className={cx(\"ui-segmented-control__button\", className)}\n __css={css}\n {...rest}\n >\n <ui.input {...getInputProps(props, mergeRefs(register, ref))} />\n <ui.span>{children}</ui.span>\n {isSelected && isMounted ? (\n <SegmentedControlCursor {...motionProps} />\n ) : null}\n </ui.label>\n )\n },\n)\n\nSegmentedControlButton.displayName = \"SegmentedControlButton\"\n\ntype SegmentedControlCursorProps = MotionProps & { className?: string }\n\nconst SegmentedControlCursor: FC<SegmentedControlCursorProps> = ({\n className,\n transition,\n ...rest\n}) => {\n const { styles } = useSegmentedControl()\n\n const css: CSSUIObject = {\n position: \"absolute\",\n zIndex: \"-10\",\n w: \"full\",\n h: \"full\",\n ...styles.cursor,\n }\n\n return (\n <Motion\n className={cx(\"ui-segmented-control__cursor\", className)}\n layoutDependency={false}\n layoutId=\"cursor\"\n transition={{\n type: \"spring\",\n bounce: 0.15,\n duration: 0.4,\n ...transition,\n }}\n __css={css}\n {...rest}\n />\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACCA,kBAKO;AAEP,oBAAoC;AACpC,oCAAqC;AACrC,4BAAiC;AACjC,+BAAkC;AAElC,mBAWO;AAEP,mBAAgE;AAoPxD;AA9OR,IAAM,EAAE,4BAA4B,gBAAgB,cAAc,QAChE,wCAAoC;AAStC,IAAM,CAAC,0BAA0B,mBAAmB,QAClD,4BAAuC;AAAA,EACrC,QAAQ;AAAA,EACR,MAAM;AACR,CAAC;AA8CI,IAAM,uBAAmB;AAAA,EAC9B,CAAC,OAAO,QAAQ;AACd,UAAM,CAAC,QAAQ,WAAW,QAAI;AAAA,MAC5B;AAAA,MACA;AAAA,IACF;AACA,QAAI;AAAA,MACF;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ,CAAC;AAAA,MACT;AAAA,MACA;AAAA,MACA,GAAG;AAAA,IACL,QAAI,4BAAe,WAAW;AAE9B,+BAAO,oBAAM;AACb,iCAAS,yBAAqB,oBAAM,CAAC;AAErC,SAAK,eAAW,6BAAe,KAAK,QAAQ;AAE5C,UAAM,cAAc,eAAe;AAEnC,UAAM,CAAC,cAAc,eAAe,QAAI,uBAAiB,EAAE;AAC3D,UAAM,CAAC,gBAAgB,iBAAiB,QAAI,uBAAkB,KAAK;AACnE,UAAM,mBAAe,qBAAuB,IAAI;AAChD,UAAM,gBAAY,qBAA+C,oBAAI,IAAI,CAAC;AAE1E,UAAM,CAAC,eAAe,gBAAgB,QAAI,oDAAqB;AAAA,MAC7D;AAAA,MACA;AAAA,MACA,UAAU,KAAK;AAAA,IACjB,CAAC;AAED,UAAM,eAAW;AAAA,MACf,CAAC,OAAsC;AACrC,YAAI,cAAc,YAAY;AAC5B,aAAG,eAAe;AAElB;AAAA,QACF;AAEA,yBAAiB,GAAG,OAAO,KAAK;AAAA,MAClC;AAAA,MACA,CAAC,YAAY,YAAY,gBAAgB;AAAA,IAC3C;AAEA,UAAM,cAAU;AAAA,MACd,CAAC,OAAe,SAAkB;AAChC,YAAI;AAAY;AAEhB,YAAI,MAAM;AACR,gBAAM,OAAO,YAAY,iBAAiB,KAAK;AAE/C,cAAI;AAAM,4BAAgB,KAAK,KAAK;AAAA,QACtC,OAAO;AACL,0BAAgB,KAAK;AAAA,QACvB;AAAA,MACF;AAAA,MACA,CAAC,aAAa,UAAU;AAAA,IAC1B;AAEA,UAAM,aAAS,0BAAY,MAAM,gBAAgB,EAAE,GAAG,CAAC,CAAC;AAExD,UAAM,wBAAgC;AAAA,MACpC,CAACA,SAAQ,CAAC,GAAGC,OAAM,UAAU;AAAA,QAC3B,OAAG,yBAAW,MAAM,CAAC,UAAU,CAAC;AAAA,QAChC,GAAGD;AAAA,QACH,SAAK,wBAAU,cAAcC,IAAG;AAAA,QAChC;AAAA,QACA,qBAAiB,uBAAS,UAAU;AAAA,QACpC,qBAAiB,uBAAS,UAAU;AAAA,QACpC,YAAQ,yBAAWD,OAAM,QAAQ,MAAM;AAAA,MACzC;AAAA,MACA,CAAC,IAAI,YAAY,YAAY,QAAQ,IAAI;AAAA,IAC3C;AAEA,UAAM,oBAAuD;AAAA,MAC3D,CAAC,EAAE,OAAO,GAAGA,OAAM,IAAI,CAAC,GAAGC,OAAM,SAAS;AA7KhD;AA8KQ,cAAM,YAAW,WAAAD,OAAM,aAAN,YAAkBA,OAAM,eAAxB,YAAsC;AACvD,cAAM,YAAW,WAAAA,OAAM,aAAN,YAAkBA,OAAM,eAAxB,YAAsC;AACvD,cAAM,UAAUA,OAAM,UAAU;AAEhC,eAAO;AAAA,UACL,OAAG,yBAAWA,QAAO,CAAC,cAAc,YAAY,CAAC;AAAA,UACjD,KAAAC;AAAA,UACA,IAAI,GAAG,EAAE,IAAI,KAAK;AAAA,UAClB,MAAM;AAAA,UACN;AAAA,UACA,UAAU,YAAY;AAAA,UACtB;AAAA,UACA;AAAA,UACA,qBAAiB,uBAAS,QAAQ;AAAA,UAClC,qBAAiB,uBAAS,QAAQ;AAAA,UAClC,oBAAgB,uBAAS,OAAO;AAAA,UAChC,kBAAc,uBAAS,UAAU,YAAY;AAAA,UAC7C,OAAO;AAAA,YACL,QAAQ;AAAA,YACR,MAAM;AAAA,YACN,QAAQ;AAAA,YACR,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,SAAS;AAAA,YACT,UAAU;AAAA,YACV,YAAY;AAAA,YACZ,UAAU;AAAA,UACZ;AAAA,UACA,cAAU;AAAA,YAAWD,OAAM;AAAA,YAAU,CAAC,OACpC,CAAC,YAAY,CAAC,WACV,SAAS,EAAmC,IAC5C,CAAC;AAAA,UACP;AAAA,QACF;AAAA,MACF;AAAA,MACA,CAAC,YAAY,YAAY,eAAe,IAAI,MAAM,cAAc,QAAQ;AAAA,IAC1E;AAEA,UAAM,oBAAuD;AAAA,MAC3D,CAAC,EAAE,OAAO,GAAGA,OAAM,IAAI,CAAC,GAAGC,OAAM,SAAS;AArNhD;AAsNQ,cAAM,YAAW,WAAAD,OAAM,aAAN,YAAkBA,OAAM,eAAxB,YAAsC;AACvD,cAAM,YAAW,WAAAA,OAAM,aAAN,YAAkBA,OAAM,eAAxB,YAAsC;AACvD,cAAM,UAAUA,OAAM,UAAU;AAChC,cAAM,UAAU,UAAU;AAE1B,eAAO;AAAA,UACL,OAAAA;AAAA,UACA,SAAK;AAAA,YACH,CAAC,SAAS,UAAU,QAAQ,IAAIA,OAAM,OAAO,IAAI;AAAA,YACjDC;AAAA,UACF;AAAA,UACA,qBAAiB,uBAAS,QAAQ;AAAA,UAClC,qBAAiB,uBAAS,QAAQ;AAAA,UAClC,oBAAgB,uBAAS,OAAO;AAAA,UAChC,kBAAc,uBAAS,OAAO;AAAA,UAC9B,0BAAsB,uBAAS,WAAW,cAAc;AAAA,UACxD,aAAS;AAAA,YAAWD,OAAM;AAAA,YAAS,MACjC,QAAQ,OAAO,YAAY,QAAQ;AAAA,UACrC;AAAA,UACA,GAAI,YAAY,WACZ;AAAA,YACE,QAAQ,CAAC;AAAA,YACT,SAAS,CAAC;AAAA,YACV,QAAQ,CAAC;AAAA,YACT,UAAU,CAAC;AAAA,YACX,eAAe,CAAC;AAAA,UAClB,IACA,CAAC;AAAA,QACP;AAAA,MACF;AAAA,MACA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,gCAAU,MAAM;AACd,iBAAO,4CAAkB,iBAAiB;AAAA,IAC5C,GAAG,CAAC,CAAC;AAEL,UAAM,MAAmB;AAAA,MACvB,UAAU;AAAA,MACV,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,GAAG,OAAO;AAAA,IACZ;AAEA,UAAM,oBAAgB,+BAAiB,QAAQ;AAC/C,QAAI,mBAAmC,CAAC;AAExC,QAAI,CAAC,cAAc,UAAU,MAAM,QAAQ;AACzC,yBAAmB,MAAM,IAAI,CAAC,EAAE,OAAO,OAAAE,QAAO,GAAGF,OAAM,GAAG,MACxD,4CAAC,0BAA+B,OAAOE,QAAQ,GAAGF,QAC/C,mBAD0B,CAE7B,CACD;AAAA,IACH,OAAO;AACL,yBAAmB;AAAA,IACrB;AAEA,QAAI,iBAAiB,QAAQ,gBAAgB,MAAM;AACjD,iBAAW,SAAS,kBAAkB;AACpC,YAAI,MAAM,SAAS;AACjB,cACG,MAAM,KAAa,gBACpB,uBAAuB;AAEvB;AAAA;AAEJ,cAAME,SAAQ,MAAM,MAAM;AAE1B,yBAAiBA,MAAK;AAEtB;AAAA,MACF;AAAA,IACF;AAEA,WACE,4CAAC,8BAA2B,OAAO,aACjC;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,EAAE,eAAe,eAAe,QAAQ,cAAc;AAAA,QAE7D,sDAAC,6BAAY,IACX;AAAA,UAAC,eAAG;AAAA,UAAH;AAAA,YACE,GAAG,kBAAkB,CAAC,GAAG,GAAG;AAAA,YAC7B,eAAW,iBAAG,wBAAwB,SAAS;AAAA,YAC/C,OAAO;AAAA,YAEN;AAAA;AAAA,QACH,GACF;AAAA;AAAA,IACF,GACF;AAAA,EAEJ;AACF;AAwBO,IAAM,6BAAyB;AAAA,EAIpC,CACE;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,CAAC,EAAE,SAAS,QAAI,2BAAa,EAAE,UAAU,KAAK,CAAC;AACrD,UAAM,EAAE,eAAe,eAAe,eAAe,OAAO,IAC1D,oBAAoB;AAEtB,UAAM,EAAE,OAAO,SAAS,IAAI,cAAc;AAAA,MACxC,UAAU,cAAc;AAAA,IAC1B,CAAC;AAED,UAAM,QAAQ;AAAA,MACZ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,MAAmB;AAAA,MACvB,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,gBAAgB;AAAA,MAChB,YAAY;AAAA,MACZ,GAAG,OAAO;AAAA,IACZ;AAEA,UAAM,aAAa,kBAAkB;AAErC,WACE;AAAA,MAAC,eAAG;AAAA,MAAH;AAAA,QACE,GAAG,kBAAc,yBAAW,OAAO,CAAC,UAAU,CAAC,CAAC;AAAA,QACjD,eAAW,iBAAG,gCAAgC,SAAS;AAAA,QACvD,OAAO;AAAA,QACN,GAAG;AAAA,QAEJ;AAAA,sDAAC,eAAG,OAAH,EAAU,GAAG,cAAc,WAAO,wBAAU,UAAU,GAAG,CAAC,GAAG;AAAA,UAC9D,4CAAC,eAAG,MAAH,EAAS,UAAS;AAAA,UAClB,cAAc,YACb,4CAAC,0BAAwB,GAAG,aAAa,IACvC;AAAA;AAAA;AAAA,IACN;AAAA,EAEJ;AACF;AAEA,uBAAuB,cAAc;AAIrC,IAAM,yBAA0D,CAAC;AAAA,EAC/D;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAM;AACJ,QAAM,EAAE,OAAO,IAAI,oBAAoB;AAEvC,QAAM,MAAmB;AAAA,IACvB,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG,OAAO;AAAA,EACZ;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAW,iBAAG,gCAAgC,SAAS;AAAA,MACvD,kBAAkB;AAAA,MAClB,UAAS;AAAA,MACT,YAAY;AAAA,QACV,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,UAAU;AAAA,QACV,GAAG;AAAA,MACL;AAAA,MACA,OAAO;AAAA,MACN,GAAG;AAAA;AAAA,EACN;AAEJ;","names":["props","ref","value"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as _yamada_ui_core from '@yamada-ui/core';
|
|
2
2
|
import { HTMLUIProps, ThemeProps } from '@yamada-ui/core';
|
|
3
|
+
import { MotionProps } from '@yamada-ui/motion';
|
|
3
4
|
import { ChangeEventHandler } from 'react';
|
|
4
5
|
|
|
5
6
|
type SegmentedControlItem = SegmentedControlButtonProps & {
|
|
@@ -41,7 +42,7 @@ type SegmentedControlOptions = {
|
|
|
41
42
|
*/
|
|
42
43
|
items?: SegmentedControlItem[];
|
|
43
44
|
};
|
|
44
|
-
type SegmentedControlProps = Omit<HTMLUIProps<"div">, "onChange"> & ThemeProps<"SegmentedControl"> & SegmentedControlOptions;
|
|
45
|
+
type SegmentedControlProps = Omit<HTMLUIProps<"div">, "value" | "defaultValue" | "onChange"> & ThemeProps<"SegmentedControl"> & SegmentedControlOptions;
|
|
45
46
|
declare const SegmentedControl: _yamada_ui_core.Component<"div", SegmentedControlProps>;
|
|
46
47
|
type SegmentedControlButtonOptions = {
|
|
47
48
|
/**
|
|
@@ -52,6 +53,10 @@ type SegmentedControlButtonOptions = {
|
|
|
52
53
|
* The callback fired when any children radio is checked or unchecked.
|
|
53
54
|
*/
|
|
54
55
|
onChange?: ChangeEventHandler<HTMLInputElement>;
|
|
56
|
+
/**
|
|
57
|
+
* Props for motion component.
|
|
58
|
+
*/
|
|
59
|
+
motionProps?: MotionProps;
|
|
55
60
|
};
|
|
56
61
|
type SegmentedControlButtonProps = Omit<HTMLUIProps<"label">, "onChange"> & Pick<SegmentedControlProps, "isDisabled" | "isReadOnly"> & SegmentedControlButtonOptions;
|
|
57
62
|
declare const SegmentedControlButton: _yamada_ui_core.Component<"input", SegmentedControlButtonProps>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as _yamada_ui_core from '@yamada-ui/core';
|
|
2
2
|
import { HTMLUIProps, ThemeProps } from '@yamada-ui/core';
|
|
3
|
+
import { MotionProps } from '@yamada-ui/motion';
|
|
3
4
|
import { ChangeEventHandler } from 'react';
|
|
4
5
|
|
|
5
6
|
type SegmentedControlItem = SegmentedControlButtonProps & {
|
|
@@ -41,7 +42,7 @@ type SegmentedControlOptions = {
|
|
|
41
42
|
*/
|
|
42
43
|
items?: SegmentedControlItem[];
|
|
43
44
|
};
|
|
44
|
-
type SegmentedControlProps = Omit<HTMLUIProps<"div">, "onChange"> & ThemeProps<"SegmentedControl"> & SegmentedControlOptions;
|
|
45
|
+
type SegmentedControlProps = Omit<HTMLUIProps<"div">, "value" | "defaultValue" | "onChange"> & ThemeProps<"SegmentedControl"> & SegmentedControlOptions;
|
|
45
46
|
declare const SegmentedControl: _yamada_ui_core.Component<"div", SegmentedControlProps>;
|
|
46
47
|
type SegmentedControlButtonOptions = {
|
|
47
48
|
/**
|
|
@@ -52,6 +53,10 @@ type SegmentedControlButtonOptions = {
|
|
|
52
53
|
* The callback fired when any children radio is checked or unchecked.
|
|
53
54
|
*/
|
|
54
55
|
onChange?: ChangeEventHandler<HTMLInputElement>;
|
|
56
|
+
/**
|
|
57
|
+
* Props for motion component.
|
|
58
|
+
*/
|
|
59
|
+
motionProps?: MotionProps;
|
|
55
60
|
};
|
|
56
61
|
type SegmentedControlButtonProps = Omit<HTMLUIProps<"label">, "onChange"> & Pick<SegmentedControlProps, "isDisabled" | "isReadOnly"> & SegmentedControlButtonOptions;
|
|
57
62
|
declare const SegmentedControlButton: _yamada_ui_core.Component<"input", SegmentedControlButtonProps>;
|
|
@@ -26,10 +26,10 @@ __export(segmented_control_exports, {
|
|
|
26
26
|
});
|
|
27
27
|
module.exports = __toCommonJS(segmented_control_exports);
|
|
28
28
|
var import_core = require("@yamada-ui/core");
|
|
29
|
+
var import_motion = require("@yamada-ui/motion");
|
|
29
30
|
var import_use_controllable_state = require("@yamada-ui/use-controllable-state");
|
|
30
31
|
var import_use_descendant = require("@yamada-ui/use-descendant");
|
|
31
32
|
var import_use_focus_visible = require("@yamada-ui/use-focus-visible");
|
|
32
|
-
var import_use_resize_observer = require("@yamada-ui/use-resize-observer");
|
|
33
33
|
var import_utils = require("@yamada-ui/utils");
|
|
34
34
|
var import_react = require("react");
|
|
35
35
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
@@ -52,48 +52,32 @@ var SegmentedControl = (0, import_core.forwardRef)(
|
|
|
52
52
|
isDisabled,
|
|
53
53
|
children,
|
|
54
54
|
items = [],
|
|
55
|
+
value,
|
|
56
|
+
defaultValue,
|
|
55
57
|
...rest
|
|
56
58
|
} = (0, import_core.omitThemeProps)(mergedProps);
|
|
57
|
-
const isMountedRef = (0, import_utils.useIsMounted)();
|
|
58
59
|
id != null ? id : id = (0, import_react.useId)();
|
|
59
60
|
name != null ? name : name = `segmented-control-${(0, import_react.useId)()}`;
|
|
60
61
|
rest.onChange = (0, import_utils.useCallbackRef)(rest.onChange);
|
|
61
62
|
const descendants = useDescendants();
|
|
62
63
|
const [focusedIndex, setFocusedIndex] = (0, import_react.useState)(-1);
|
|
63
64
|
const [isFocusVisible, setIsFocusVisible] = (0, import_react.useState)(false);
|
|
64
|
-
const [observerRef, containerRect] = (0, import_use_resize_observer.useResizeObserver)();
|
|
65
65
|
const containerRef = (0, import_react.useRef)(null);
|
|
66
66
|
const labelRefs = (0, import_react.useRef)(/* @__PURE__ */ new Map());
|
|
67
|
-
const [
|
|
68
|
-
value
|
|
69
|
-
defaultValue
|
|
67
|
+
const [selectedValue, setSelectedValue] = (0, import_use_controllable_state.useControllableState)({
|
|
68
|
+
value,
|
|
69
|
+
defaultValue,
|
|
70
70
|
onChange: rest.onChange
|
|
71
71
|
});
|
|
72
|
-
const getActivePosition = (0, import_react.useCallback)(() => {
|
|
73
|
-
const rect = { width: 0, height: 0, x: 0, y: 0 };
|
|
74
|
-
const el = labelRefs.current.get(value);
|
|
75
|
-
if (!el || !containerRef.current || !observerRef.current)
|
|
76
|
-
return rect;
|
|
77
|
-
const { paddingLeft, paddingTop } = getComputedStyle(containerRef.current);
|
|
78
|
-
const gutterX = parseFloat(paddingLeft) || 0;
|
|
79
|
-
const gutterY = parseFloat(paddingTop) || 0;
|
|
80
|
-
let { width, height } = el.getBoundingClientRect();
|
|
81
|
-
rect.x = el.offsetLeft - gutterX;
|
|
82
|
-
rect.y = el.offsetTop - gutterY;
|
|
83
|
-
rect.width = width * (el.offsetWidth / width) || 0;
|
|
84
|
-
rect.height = height * (el.offsetWidth / width) || 0;
|
|
85
|
-
return rect;
|
|
86
|
-
}, [observerRef, value]);
|
|
87
|
-
const [activePosition, setActivePosition] = (0, import_react.useState)(getActivePosition);
|
|
88
72
|
const onChange = (0, import_react.useCallback)(
|
|
89
73
|
(ev) => {
|
|
90
74
|
if (isDisabled || isReadOnly) {
|
|
91
75
|
ev.preventDefault();
|
|
92
76
|
return;
|
|
93
77
|
}
|
|
94
|
-
|
|
78
|
+
setSelectedValue(ev.target.value);
|
|
95
79
|
},
|
|
96
|
-
[isDisabled, isReadOnly,
|
|
80
|
+
[isDisabled, isReadOnly, setSelectedValue]
|
|
97
81
|
);
|
|
98
82
|
const onFocus = (0, import_react.useCallback)(
|
|
99
83
|
(index, skip) => {
|
|
@@ -112,39 +96,22 @@ var SegmentedControl = (0, import_core.forwardRef)(
|
|
|
112
96
|
const onBlur = (0, import_react.useCallback)(() => setFocusedIndex(-1), []);
|
|
113
97
|
const getContainerProps = (0, import_react.useCallback)(
|
|
114
98
|
(props2 = {}, ref2 = null) => ({
|
|
115
|
-
...(0, import_utils.omitObject)(rest, ["
|
|
99
|
+
...(0, import_utils.omitObject)(rest, ["onChange"]),
|
|
116
100
|
...props2,
|
|
117
|
-
ref: (0, import_utils.mergeRefs)(containerRef,
|
|
101
|
+
ref: (0, import_utils.mergeRefs)(containerRef, ref2),
|
|
118
102
|
id,
|
|
119
103
|
"aria-disabled": (0, import_utils.ariaAttr)(isDisabled),
|
|
120
104
|
"aria-readonly": (0, import_utils.ariaAttr)(isReadOnly),
|
|
121
105
|
onBlur: (0, import_utils.handlerAll)(props2.onBlur, onBlur)
|
|
122
106
|
}),
|
|
123
|
-
[id, isDisabled, isReadOnly,
|
|
124
|
-
);
|
|
125
|
-
const getActiveProps = (0, import_react.useCallback)(
|
|
126
|
-
(props2 = {}, ref2 = null) => {
|
|
127
|
-
const { width, height, x, y } = activePosition;
|
|
128
|
-
return {
|
|
129
|
-
...props2,
|
|
130
|
-
ref: ref2,
|
|
131
|
-
style: {
|
|
132
|
-
position: "absolute",
|
|
133
|
-
zIndex: 1,
|
|
134
|
-
width,
|
|
135
|
-
height,
|
|
136
|
-
transform: `translate(${x}px, ${y}px)`
|
|
137
|
-
}
|
|
138
|
-
};
|
|
139
|
-
},
|
|
140
|
-
[activePosition]
|
|
107
|
+
[id, isDisabled, isReadOnly, onBlur, rest]
|
|
141
108
|
);
|
|
142
109
|
const getInputProps = (0, import_react.useCallback)(
|
|
143
110
|
({ index, ...props2 } = {}, ref2 = null) => {
|
|
144
111
|
var _a, _b, _c, _d;
|
|
145
112
|
const disabled = (_b = (_a = props2.disabled) != null ? _a : props2.isDisabled) != null ? _b : isDisabled;
|
|
146
113
|
const readOnly = (_d = (_c = props2.readOnly) != null ? _c : props2.isReadOnly) != null ? _d : isReadOnly;
|
|
147
|
-
const checked = props2.value ===
|
|
114
|
+
const checked = props2.value === selectedValue;
|
|
148
115
|
return {
|
|
149
116
|
...(0, import_utils.omitObject)(props2, ["isDisabled", "isReadOnly"]),
|
|
150
117
|
ref: ref2,
|
|
@@ -175,14 +142,14 @@ var SegmentedControl = (0, import_core.forwardRef)(
|
|
|
175
142
|
)
|
|
176
143
|
};
|
|
177
144
|
},
|
|
178
|
-
[isDisabled, isReadOnly,
|
|
145
|
+
[isDisabled, isReadOnly, selectedValue, id, name, focusedIndex, onChange]
|
|
179
146
|
);
|
|
180
147
|
const getLabelProps = (0, import_react.useCallback)(
|
|
181
148
|
({ index, ...props2 } = {}, ref2 = null) => {
|
|
182
149
|
var _a, _b, _c, _d;
|
|
183
150
|
const disabled = (_b = (_a = props2.disabled) != null ? _a : props2.isDisabled) != null ? _b : isDisabled;
|
|
184
151
|
const readOnly = (_d = (_c = props2.readOnly) != null ? _c : props2.isReadOnly) != null ? _d : isReadOnly;
|
|
185
|
-
const checked = props2.value ===
|
|
152
|
+
const checked = props2.value === selectedValue;
|
|
186
153
|
const focused = index === focusedIndex;
|
|
187
154
|
return {
|
|
188
155
|
props: props2,
|
|
@@ -205,18 +172,21 @@ var SegmentedControl = (0, import_core.forwardRef)(
|
|
|
205
172
|
_focus: {},
|
|
206
173
|
_invalid: {},
|
|
207
174
|
_focusVisible: {}
|
|
208
|
-
} : {}
|
|
209
|
-
style: { position: "relative", zIndex: 2 }
|
|
175
|
+
} : {}
|
|
210
176
|
};
|
|
211
177
|
},
|
|
212
|
-
[
|
|
178
|
+
[
|
|
179
|
+
focusedIndex,
|
|
180
|
+
isDisabled,
|
|
181
|
+
isFocusVisible,
|
|
182
|
+
isReadOnly,
|
|
183
|
+
onFocus,
|
|
184
|
+
selectedValue
|
|
185
|
+
]
|
|
213
186
|
);
|
|
214
187
|
(0, import_react.useEffect)(() => {
|
|
215
188
|
return (0, import_use_focus_visible.trackFocusVisible)(setIsFocusVisible);
|
|
216
189
|
}, []);
|
|
217
|
-
(0, import_react.useEffect)(() => {
|
|
218
|
-
setActivePosition(getActivePosition());
|
|
219
|
-
}, [focusedIndex, containerRect, value, getActivePosition]);
|
|
220
190
|
const css = {
|
|
221
191
|
position: "relative",
|
|
222
192
|
display: "inline-flex",
|
|
@@ -230,38 +200,30 @@ var SegmentedControl = (0, import_core.forwardRef)(
|
|
|
230
200
|
} else {
|
|
231
201
|
computedChildren = validChildren;
|
|
232
202
|
}
|
|
233
|
-
if (
|
|
203
|
+
if (selectedValue == null && defaultValue == null) {
|
|
234
204
|
for (const child of computedChildren) {
|
|
235
|
-
if (child.type !== SegmentedControlButton)
|
|
236
|
-
|
|
205
|
+
if (child.type !== SegmentedControlButton) {
|
|
206
|
+
if (child.type.displayName !== SegmentedControlButton.displayName)
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
237
209
|
const value2 = child.props.value;
|
|
238
|
-
|
|
210
|
+
setSelectedValue(value2);
|
|
239
211
|
break;
|
|
240
212
|
}
|
|
241
213
|
}
|
|
242
214
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DescendantsContextProvider, { value: descendants, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
243
215
|
SegmentedControlProvider,
|
|
244
216
|
{
|
|
245
|
-
value: { getInputProps, getLabelProps, styles },
|
|
246
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.
|
|
217
|
+
value: { getInputProps, getLabelProps, styles, selectedValue },
|
|
218
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_motion.LayoutGroup, { id, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
247
219
|
import_core.ui.div,
|
|
248
220
|
{
|
|
249
221
|
...getContainerProps({}, ref),
|
|
250
222
|
className: (0, import_utils.cx)("ui-segmented-control", className),
|
|
251
223
|
__css: css,
|
|
252
|
-
children:
|
|
253
|
-
isMountedRef.current ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
254
|
-
import_core.ui.span,
|
|
255
|
-
{
|
|
256
|
-
className: "ui-segmented-control__active",
|
|
257
|
-
...getActiveProps(),
|
|
258
|
-
__css: styles.active
|
|
259
|
-
}
|
|
260
|
-
) : null,
|
|
261
|
-
computedChildren
|
|
262
|
-
]
|
|
224
|
+
children: computedChildren
|
|
263
225
|
}
|
|
264
|
-
)
|
|
226
|
+
) })
|
|
265
227
|
}
|
|
266
228
|
) });
|
|
267
229
|
}
|
|
@@ -276,9 +238,11 @@ var SegmentedControlButton = (0, import_core.forwardRef)(
|
|
|
276
238
|
value,
|
|
277
239
|
onChange,
|
|
278
240
|
children,
|
|
241
|
+
motionProps,
|
|
279
242
|
...rest
|
|
280
243
|
}, ref) => {
|
|
281
|
-
const
|
|
244
|
+
const [, isMounted] = (0, import_utils.useIsMounted)({ rerender: true });
|
|
245
|
+
const { selectedValue, getInputProps, getLabelProps, styles } = useSegmentedControl();
|
|
282
246
|
const { index, register } = useDescendant({
|
|
283
247
|
disabled: isDisabled || isReadOnly
|
|
284
248
|
});
|
|
@@ -292,6 +256,7 @@ var SegmentedControlButton = (0, import_core.forwardRef)(
|
|
|
292
256
|
isReadOnly
|
|
293
257
|
};
|
|
294
258
|
const css = {
|
|
259
|
+
position: "relative",
|
|
295
260
|
cursor: "pointer",
|
|
296
261
|
flex: "1 1 0%",
|
|
297
262
|
display: "inline-flex",
|
|
@@ -299,6 +264,7 @@ var SegmentedControlButton = (0, import_core.forwardRef)(
|
|
|
299
264
|
alignItems: "center",
|
|
300
265
|
...styles.button
|
|
301
266
|
};
|
|
267
|
+
const isSelected = selectedValue === value;
|
|
302
268
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
303
269
|
import_core.ui.label,
|
|
304
270
|
{
|
|
@@ -308,12 +274,44 @@ var SegmentedControlButton = (0, import_core.forwardRef)(
|
|
|
308
274
|
...rest,
|
|
309
275
|
children: [
|
|
310
276
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.ui.input, { ...getInputProps(props, (0, import_utils.mergeRefs)(register, ref)) }),
|
|
311
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.ui.span, { children })
|
|
277
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.ui.span, { children }),
|
|
278
|
+
isSelected && isMounted ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SegmentedControlCursor, { ...motionProps }) : null
|
|
312
279
|
]
|
|
313
280
|
}
|
|
314
281
|
);
|
|
315
282
|
}
|
|
316
283
|
);
|
|
284
|
+
SegmentedControlButton.displayName = "SegmentedControlButton";
|
|
285
|
+
var SegmentedControlCursor = ({
|
|
286
|
+
className,
|
|
287
|
+
transition,
|
|
288
|
+
...rest
|
|
289
|
+
}) => {
|
|
290
|
+
const { styles } = useSegmentedControl();
|
|
291
|
+
const css = {
|
|
292
|
+
position: "absolute",
|
|
293
|
+
zIndex: "-10",
|
|
294
|
+
w: "full",
|
|
295
|
+
h: "full",
|
|
296
|
+
...styles.cursor
|
|
297
|
+
};
|
|
298
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
299
|
+
import_motion.Motion,
|
|
300
|
+
{
|
|
301
|
+
className: (0, import_utils.cx)("ui-segmented-control__cursor", className),
|
|
302
|
+
layoutDependency: false,
|
|
303
|
+
layoutId: "cursor",
|
|
304
|
+
transition: {
|
|
305
|
+
type: "spring",
|
|
306
|
+
bounce: 0.15,
|
|
307
|
+
duration: 0.4,
|
|
308
|
+
...transition
|
|
309
|
+
},
|
|
310
|
+
__css: css,
|
|
311
|
+
...rest
|
|
312
|
+
}
|
|
313
|
+
);
|
|
314
|
+
};
|
|
317
315
|
// Annotate the CommonJS export names for ESM import in node:
|
|
318
316
|
0 && (module.exports = {
|
|
319
317
|
SegmentedControl,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/segmented-control.tsx"],"sourcesContent":["import type { CSSUIObject, HTMLUIProps, ThemeProps } from \"@yamada-ui/core\"\nimport {\n ui,\n forwardRef,\n useMultiComponentStyle,\n omitThemeProps,\n} from \"@yamada-ui/core\"\nimport { useControllableState } from \"@yamada-ui/use-controllable-state\"\nimport { createDescendant } from \"@yamada-ui/use-descendant\"\nimport { trackFocusVisible } from \"@yamada-ui/use-focus-visible\"\nimport { useResizeObserver } from \"@yamada-ui/use-resize-observer\"\nimport type { PropGetter, RequiredPropGetter } from \"@yamada-ui/utils\"\nimport {\n ariaAttr,\n createContext,\n cx,\n dataAttr,\n getValidChildren,\n handlerAll,\n mergeRefs,\n omitObject,\n useCallbackRef,\n useIsMounted,\n} from \"@yamada-ui/utils\"\nimport type { ChangeEvent, ChangeEventHandler, ReactElement } from \"react\"\nimport { useCallback, useEffect, useId, useRef, useState } from \"react\"\n\nexport type SegmentedControlItem = SegmentedControlButtonProps & {\n label?: string\n}\n\nconst { DescendantsContextProvider, useDescendants, useDescendant } =\n createDescendant<HTMLButtonElement>()\n\ntype SegmentedControlContext = {\n getInputProps: RequiredPropGetter<{ index: number }>\n getLabelProps: RequiredPropGetter<{ index: number }>\n styles: Record<string, CSSUIObject>\n}\n\nconst [SegmentedControlProvider, useSegmentedControl] =\n createContext<SegmentedControlContext>({\n strict: false,\n name: \"SegmentedControlContext\",\n })\n\ntype SegmentedControlOptions = {\n /**\n * The HTML `name` attribute used for forms.\n */\n name?: string\n /**\n * The value of the segmented control.\n */\n value?: string\n /**\n * The initial value of the segmented control.\n */\n defaultValue?: string\n /**\n * The callback fired when any children radio is checked or unchecked.\n */\n onChange?: (value: string) => void\n /**\n * If `true`, the segmented control will be readonly.\n *\n * @default false\n */\n isReadOnly?: boolean\n /**\n * If `true`, the segmented control will be disabled.\n *\n * @default false\n */\n isDisabled?: boolean\n /**\n * If provided, generate segmented control buttons but based on items.\n *\n * @default '[]'\n */\n items?: SegmentedControlItem[]\n}\n\nexport type SegmentedControlProps = Omit<HTMLUIProps<\"div\">, \"onChange\"> &\n ThemeProps<\"SegmentedControl\"> &\n SegmentedControlOptions\n\nexport const SegmentedControl = forwardRef<SegmentedControlProps, \"div\">(\n (props, ref) => {\n const [styles, mergedProps] = useMultiComponentStyle(\n \"SegmentedControl\",\n props,\n )\n let {\n className,\n id,\n name,\n isReadOnly,\n isDisabled,\n children,\n items = [],\n ...rest\n } = omitThemeProps(mergedProps)\n const isMountedRef = useIsMounted()\n\n id ??= useId()\n name ??= `segmented-control-${useId()}`\n\n rest.onChange = useCallbackRef(rest.onChange)\n\n const descendants = useDescendants()\n\n const [focusedIndex, setFocusedIndex] = useState<number>(-1)\n const [isFocusVisible, setIsFocusVisible] = useState<boolean>(false)\n const [observerRef, containerRect] = useResizeObserver()\n const containerRef = useRef<HTMLDivElement>(null)\n const labelRefs = useRef<Map<string | number, HTMLLabelElement>>(new Map())\n\n const [value, setValue] = useControllableState({\n value: rest.value,\n defaultValue: rest.defaultValue,\n onChange: rest.onChange,\n })\n\n const getActivePosition = useCallback(() => {\n const rect = { width: 0, height: 0, x: 0, y: 0 }\n\n const el = labelRefs.current.get(value)\n\n if (!el || !containerRef.current || !observerRef.current) return rect\n\n const { paddingLeft, paddingTop } = getComputedStyle(containerRef.current)\n\n const gutterX = parseFloat(paddingLeft) || 0\n const gutterY = parseFloat(paddingTop) || 0\n\n let { width, height } = el.getBoundingClientRect()\n rect.x = el.offsetLeft - gutterX\n rect.y = el.offsetTop - gutterY\n\n rect.width = width * (el.offsetWidth / width) || 0\n rect.height = height * (el.offsetWidth / width) || 0\n\n return rect\n }, [observerRef, value])\n\n const [activePosition, setActivePosition] = useState(getActivePosition)\n\n const onChange = useCallback(\n (ev: ChangeEvent<HTMLInputElement>) => {\n if (isDisabled || isReadOnly) {\n ev.preventDefault()\n\n return\n }\n\n setValue(ev.target.value)\n },\n [isDisabled, isReadOnly, setValue],\n )\n\n const onFocus = useCallback(\n (index: number, skip: boolean) => {\n if (isDisabled) return\n\n if (skip) {\n const next = descendants.enabledNextValue(index)\n\n if (next) setFocusedIndex(next.index)\n } else {\n setFocusedIndex(index)\n }\n },\n [descendants, isDisabled],\n )\n\n const onBlur = useCallback(() => setFocusedIndex(-1), [])\n\n const getContainerProps: PropGetter = useCallback(\n (props = {}, ref = null) => ({\n ...omitObject(rest, [\"value\", \"defaultValue\", \"onChange\"]),\n ...props,\n ref: mergeRefs(containerRef, observerRef, ref),\n id,\n \"aria-disabled\": ariaAttr(isDisabled),\n \"aria-readonly\": ariaAttr(isReadOnly),\n onBlur: handlerAll(props.onBlur, onBlur),\n }),\n [id, isDisabled, isReadOnly, observerRef, onBlur, rest],\n )\n\n const getActiveProps: PropGetter = useCallback(\n (props = {}, ref = null) => {\n const { width, height, x, y } = activePosition\n\n return {\n ...props,\n ref,\n style: {\n position: \"absolute\",\n zIndex: 1,\n width,\n height,\n transform: `translate(${x}px, ${y}px)`,\n },\n }\n },\n [activePosition],\n )\n\n const getInputProps: RequiredPropGetter<{ index: number }> = useCallback(\n ({ index, ...props } = {}, ref = null) => {\n const disabled = props.disabled ?? props.isDisabled ?? isDisabled\n const readOnly = props.readOnly ?? props.isReadOnly ?? isReadOnly\n const checked = props.value === value\n\n return {\n ...omitObject(props, [\"isDisabled\", \"isReadOnly\"]),\n ref,\n id: `${id}-${index}`,\n type: \"radio\",\n name,\n disabled: disabled || readOnly,\n readOnly,\n checked,\n \"aria-disabled\": ariaAttr(disabled),\n \"aria-readonly\": ariaAttr(readOnly),\n \"data-checked\": dataAttr(checked),\n \"data-focus\": dataAttr(index === focusedIndex),\n style: {\n border: \"0px\",\n clip: \"rect(0px, 0px, 0px, 0px)\",\n height: \"1px\",\n width: \"1px\",\n margin: \"-1px\",\n padding: \"0px\",\n overflow: \"hidden\",\n whiteSpace: \"nowrap\",\n position: \"absolute\",\n },\n onChange: handlerAll(props.onChange, (ev) =>\n !disabled && !readOnly\n ? onChange(ev as ChangeEvent<HTMLInputElement>)\n : {},\n ),\n }\n },\n [isDisabled, isReadOnly, value, id, name, focusedIndex, onChange],\n )\n\n const getLabelProps: RequiredPropGetter<{ index: number }> = useCallback(\n ({ index, ...props } = {}, ref = null) => {\n const disabled = props.disabled ?? props.isDisabled ?? isDisabled\n const readOnly = props.readOnly ?? props.isReadOnly ?? isReadOnly\n const checked = props.value === value\n const focused = index === focusedIndex\n\n return {\n props,\n ref: mergeRefs(\n (node) => labelRefs.current.set(props.value, node),\n ref,\n ),\n \"aria-disabled\": ariaAttr(disabled),\n \"aria-readonly\": ariaAttr(readOnly),\n \"data-checked\": dataAttr(checked),\n \"data-focus\": dataAttr(focused),\n \"data-focus-visible\": dataAttr(focused && isFocusVisible),\n onFocus: handlerAll(props.onFocus, () =>\n onFocus(index, disabled || readOnly),\n ),\n ...(disabled || readOnly\n ? {\n _hover: {},\n _active: {},\n _focus: {},\n _invalid: {},\n _focusVisible: {},\n }\n : {}),\n style: { position: \"relative\", zIndex: 2 },\n }\n },\n [focusedIndex, isDisabled, isFocusVisible, isReadOnly, onFocus, value],\n )\n\n useEffect(() => {\n return trackFocusVisible(setIsFocusVisible)\n }, [])\n\n useEffect(() => {\n setActivePosition(getActivePosition())\n }, [focusedIndex, containerRect, value, getActivePosition])\n\n const css: CSSUIObject = {\n position: \"relative\",\n display: \"inline-flex\",\n alignItems: \"center\",\n ...styles.container,\n }\n\n const validChildren = getValidChildren(children)\n let computedChildren: ReactElement[] = []\n\n if (!validChildren.length && items.length) {\n computedChildren = items.map(({ label, value, ...props }, i) => (\n <SegmentedControlButton key={i} value={value} {...props}>\n {label}\n </SegmentedControlButton>\n ))\n } else {\n computedChildren = validChildren\n }\n\n if (value == null && rest.defaultValue == null) {\n for (const child of computedChildren) {\n if (child.type !== SegmentedControlButton) continue\n\n const value = child.props.value\n\n setValue(value)\n\n break\n }\n }\n\n return (\n <DescendantsContextProvider value={descendants}>\n <SegmentedControlProvider\n value={{ getInputProps, getLabelProps, styles }}\n >\n <ui.div\n {...getContainerProps({}, ref)}\n className={cx(\"ui-segmented-control\", className)}\n __css={css}\n >\n {isMountedRef.current ? (\n <ui.span\n className=\"ui-segmented-control__active\"\n {...getActiveProps()}\n __css={styles.active}\n />\n ) : null}\n\n {computedChildren}\n </ui.div>\n </SegmentedControlProvider>\n </DescendantsContextProvider>\n )\n },\n)\n\ntype SegmentedControlButtonOptions = {\n /**\n * The value of the segmented control button.\n */\n value: string | number\n /**\n * The callback fired when any children radio is checked or unchecked.\n */\n onChange?: ChangeEventHandler<HTMLInputElement>\n}\n\nexport type SegmentedControlButtonProps = Omit<\n HTMLUIProps<\"label\">,\n \"onChange\"\n> &\n Pick<SegmentedControlProps, \"isDisabled\" | \"isReadOnly\"> &\n SegmentedControlButtonOptions\n\nexport const SegmentedControlButton = forwardRef<\n SegmentedControlButtonProps,\n \"input\"\n>(\n (\n {\n className,\n disabled,\n readOnly,\n isDisabled,\n isReadOnly,\n value,\n onChange,\n children,\n ...rest\n },\n ref,\n ) => {\n const { getInputProps, getLabelProps, styles } = useSegmentedControl()\n\n const { index, register } = useDescendant({\n disabled: isDisabled || isReadOnly,\n })\n\n const props = {\n index,\n value,\n onChange,\n disabled,\n readOnly,\n isDisabled,\n isReadOnly,\n }\n\n const css: CSSUIObject = {\n cursor: \"pointer\",\n flex: \"1 1 0%\",\n display: \"inline-flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n ...styles.button,\n }\n\n return (\n <ui.label\n {...getLabelProps(omitObject(props, [\"onChange\"]))}\n className={cx(\"ui-segmented-control__button\", className)}\n __css={css}\n {...rest}\n >\n <ui.input {...getInputProps(props, mergeRefs(register, ref))} />\n <ui.span>{children}</ui.span>\n </ui.label>\n )\n },\n)\n"],"mappings":"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","names":["props","ref","value"]}
|
|
1
|
+
{"version":3,"sources":["../src/segmented-control.tsx"],"sourcesContent":["import type { CSSUIObject, HTMLUIProps, ThemeProps } from \"@yamada-ui/core\"\nimport {\n ui,\n forwardRef,\n useMultiComponentStyle,\n omitThemeProps,\n} from \"@yamada-ui/core\"\nimport type { MotionProps } from \"@yamada-ui/motion\"\nimport { LayoutGroup, Motion } from \"@yamada-ui/motion\"\nimport { useControllableState } from \"@yamada-ui/use-controllable-state\"\nimport { createDescendant } from \"@yamada-ui/use-descendant\"\nimport { trackFocusVisible } from \"@yamada-ui/use-focus-visible\"\nimport type { PropGetter, RequiredPropGetter } from \"@yamada-ui/utils\"\nimport {\n ariaAttr,\n createContext,\n cx,\n dataAttr,\n getValidChildren,\n handlerAll,\n mergeRefs,\n omitObject,\n useCallbackRef,\n useIsMounted,\n} from \"@yamada-ui/utils\"\nimport type { ChangeEvent, ChangeEventHandler, FC, ReactElement } from \"react\"\nimport { useCallback, useEffect, useId, useRef, useState } from \"react\"\n\nexport type SegmentedControlItem = SegmentedControlButtonProps & {\n label?: string\n}\n\nconst { DescendantsContextProvider, useDescendants, useDescendant } =\n createDescendant<HTMLButtonElement>()\n\ntype SegmentedControlContext = {\n selectedValue: string\n getInputProps: RequiredPropGetter<{ index: number }>\n getLabelProps: RequiredPropGetter<{ index: number }>\n styles: Record<string, CSSUIObject>\n}\n\nconst [SegmentedControlProvider, useSegmentedControl] =\n createContext<SegmentedControlContext>({\n strict: false,\n name: \"SegmentedControlContext\",\n })\n\ntype SegmentedControlOptions = {\n /**\n * The HTML `name` attribute used for forms.\n */\n name?: string\n /**\n * The value of the segmented control.\n */\n value?: string\n /**\n * The initial value of the segmented control.\n */\n defaultValue?: string\n /**\n * The callback fired when any children radio is checked or unchecked.\n */\n onChange?: (value: string) => void\n /**\n * If `true`, the segmented control will be readonly.\n *\n * @default false\n */\n isReadOnly?: boolean\n /**\n * If `true`, the segmented control will be disabled.\n *\n * @default false\n */\n isDisabled?: boolean\n /**\n * If provided, generate segmented control buttons but based on items.\n *\n * @default '[]'\n */\n items?: SegmentedControlItem[]\n}\n\nexport type SegmentedControlProps = Omit<\n HTMLUIProps<\"div\">,\n \"value\" | \"defaultValue\" | \"onChange\"\n> &\n ThemeProps<\"SegmentedControl\"> &\n SegmentedControlOptions\n\nexport const SegmentedControl = forwardRef<SegmentedControlProps, \"div\">(\n (props, ref) => {\n const [styles, mergedProps] = useMultiComponentStyle(\n \"SegmentedControl\",\n props,\n )\n let {\n className,\n id,\n name,\n isReadOnly,\n isDisabled,\n children,\n items = [],\n value,\n defaultValue,\n ...rest\n } = omitThemeProps(mergedProps)\n\n id ??= useId()\n name ??= `segmented-control-${useId()}`\n\n rest.onChange = useCallbackRef(rest.onChange)\n\n const descendants = useDescendants()\n\n const [focusedIndex, setFocusedIndex] = useState<number>(-1)\n const [isFocusVisible, setIsFocusVisible] = useState<boolean>(false)\n const containerRef = useRef<HTMLDivElement>(null)\n const labelRefs = useRef<Map<string | number, HTMLLabelElement>>(new Map())\n\n const [selectedValue, setSelectedValue] = useControllableState({\n value,\n defaultValue,\n onChange: rest.onChange,\n })\n\n const onChange = useCallback(\n (ev: ChangeEvent<HTMLInputElement>) => {\n if (isDisabled || isReadOnly) {\n ev.preventDefault()\n\n return\n }\n\n setSelectedValue(ev.target.value)\n },\n [isDisabled, isReadOnly, setSelectedValue],\n )\n\n const onFocus = useCallback(\n (index: number, skip: boolean) => {\n if (isDisabled) return\n\n if (skip) {\n const next = descendants.enabledNextValue(index)\n\n if (next) setFocusedIndex(next.index)\n } else {\n setFocusedIndex(index)\n }\n },\n [descendants, isDisabled],\n )\n\n const onBlur = useCallback(() => setFocusedIndex(-1), [])\n\n const getContainerProps: PropGetter = useCallback(\n (props = {}, ref = null) => ({\n ...omitObject(rest, [\"onChange\"]),\n ...props,\n ref: mergeRefs(containerRef, ref),\n id,\n \"aria-disabled\": ariaAttr(isDisabled),\n \"aria-readonly\": ariaAttr(isReadOnly),\n onBlur: handlerAll(props.onBlur, onBlur),\n }),\n [id, isDisabled, isReadOnly, onBlur, rest],\n )\n\n const getInputProps: RequiredPropGetter<{ index: number }> = useCallback(\n ({ index, ...props } = {}, ref = null) => {\n const disabled = props.disabled ?? props.isDisabled ?? isDisabled\n const readOnly = props.readOnly ?? props.isReadOnly ?? isReadOnly\n const checked = props.value === selectedValue\n\n return {\n ...omitObject(props, [\"isDisabled\", \"isReadOnly\"]),\n ref,\n id: `${id}-${index}`,\n type: \"radio\",\n name,\n disabled: disabled || readOnly,\n readOnly,\n checked,\n \"aria-disabled\": ariaAttr(disabled),\n \"aria-readonly\": ariaAttr(readOnly),\n \"data-checked\": dataAttr(checked),\n \"data-focus\": dataAttr(index === focusedIndex),\n style: {\n border: \"0px\",\n clip: \"rect(0px, 0px, 0px, 0px)\",\n height: \"1px\",\n width: \"1px\",\n margin: \"-1px\",\n padding: \"0px\",\n overflow: \"hidden\",\n whiteSpace: \"nowrap\",\n position: \"absolute\",\n },\n onChange: handlerAll(props.onChange, (ev) =>\n !disabled && !readOnly\n ? onChange(ev as ChangeEvent<HTMLInputElement>)\n : {},\n ),\n }\n },\n [isDisabled, isReadOnly, selectedValue, id, name, focusedIndex, onChange],\n )\n\n const getLabelProps: RequiredPropGetter<{ index: number }> = useCallback(\n ({ index, ...props } = {}, ref = null) => {\n const disabled = props.disabled ?? props.isDisabled ?? isDisabled\n const readOnly = props.readOnly ?? props.isReadOnly ?? isReadOnly\n const checked = props.value === selectedValue\n const focused = index === focusedIndex\n\n return {\n props,\n ref: mergeRefs(\n (node) => labelRefs.current.set(props.value, node),\n ref,\n ),\n \"aria-disabled\": ariaAttr(disabled),\n \"aria-readonly\": ariaAttr(readOnly),\n \"data-checked\": dataAttr(checked),\n \"data-focus\": dataAttr(focused),\n \"data-focus-visible\": dataAttr(focused && isFocusVisible),\n onFocus: handlerAll(props.onFocus, () =>\n onFocus(index, disabled || readOnly),\n ),\n ...(disabled || readOnly\n ? {\n _hover: {},\n _active: {},\n _focus: {},\n _invalid: {},\n _focusVisible: {},\n }\n : {}),\n }\n },\n [\n focusedIndex,\n isDisabled,\n isFocusVisible,\n isReadOnly,\n onFocus,\n selectedValue,\n ],\n )\n\n useEffect(() => {\n return trackFocusVisible(setIsFocusVisible)\n }, [])\n\n const css: CSSUIObject = {\n position: \"relative\",\n display: \"inline-flex\",\n alignItems: \"center\",\n ...styles.container,\n }\n\n const validChildren = getValidChildren(children)\n let computedChildren: ReactElement[] = []\n\n if (!validChildren.length && items.length) {\n computedChildren = items.map(({ label, value, ...props }, i) => (\n <SegmentedControlButton key={i} value={value} {...props}>\n {label}\n </SegmentedControlButton>\n ))\n } else {\n computedChildren = validChildren\n }\n\n if (selectedValue == null && defaultValue == null) {\n for (const child of computedChildren) {\n if (child.type !== SegmentedControlButton)\n if (\n (child.type as any).displayName !==\n SegmentedControlButton.displayName\n )\n continue\n\n const value = child.props.value\n\n setSelectedValue(value)\n\n break\n }\n }\n\n return (\n <DescendantsContextProvider value={descendants}>\n <SegmentedControlProvider\n value={{ getInputProps, getLabelProps, styles, selectedValue }}\n >\n <LayoutGroup id={id}>\n <ui.div\n {...getContainerProps({}, ref)}\n className={cx(\"ui-segmented-control\", className)}\n __css={css}\n >\n {computedChildren}\n </ui.div>\n </LayoutGroup>\n </SegmentedControlProvider>\n </DescendantsContextProvider>\n )\n },\n)\n\ntype SegmentedControlButtonOptions = {\n /**\n * The value of the segmented control button.\n */\n value: string | number\n /**\n * The callback fired when any children radio is checked or unchecked.\n */\n onChange?: ChangeEventHandler<HTMLInputElement>\n /**\n * Props for motion component.\n */\n motionProps?: MotionProps\n}\n\nexport type SegmentedControlButtonProps = Omit<\n HTMLUIProps<\"label\">,\n \"onChange\"\n> &\n Pick<SegmentedControlProps, \"isDisabled\" | \"isReadOnly\"> &\n SegmentedControlButtonOptions\n\nexport const SegmentedControlButton = forwardRef<\n SegmentedControlButtonProps,\n \"input\"\n>(\n (\n {\n className,\n disabled,\n readOnly,\n isDisabled,\n isReadOnly,\n value,\n onChange,\n children,\n motionProps,\n ...rest\n },\n ref,\n ) => {\n const [, isMounted] = useIsMounted({ rerender: true })\n const { selectedValue, getInputProps, getLabelProps, styles } =\n useSegmentedControl()\n\n const { index, register } = useDescendant({\n disabled: isDisabled || isReadOnly,\n })\n\n const props = {\n index,\n value,\n onChange,\n disabled,\n readOnly,\n isDisabled,\n isReadOnly,\n }\n\n const css: CSSUIObject = {\n position: \"relative\",\n cursor: \"pointer\",\n flex: \"1 1 0%\",\n display: \"inline-flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n ...styles.button,\n }\n\n const isSelected = selectedValue === value\n\n return (\n <ui.label\n {...getLabelProps(omitObject(props, [\"onChange\"]))}\n className={cx(\"ui-segmented-control__button\", className)}\n __css={css}\n {...rest}\n >\n <ui.input {...getInputProps(props, mergeRefs(register, ref))} />\n <ui.span>{children}</ui.span>\n {isSelected && isMounted ? (\n <SegmentedControlCursor {...motionProps} />\n ) : null}\n </ui.label>\n )\n },\n)\n\nSegmentedControlButton.displayName = \"SegmentedControlButton\"\n\ntype SegmentedControlCursorProps = MotionProps & { className?: string }\n\nconst SegmentedControlCursor: FC<SegmentedControlCursorProps> = ({\n className,\n transition,\n ...rest\n}) => {\n const { styles } = useSegmentedControl()\n\n const css: CSSUIObject = {\n position: \"absolute\",\n zIndex: \"-10\",\n w: \"full\",\n h: \"full\",\n ...styles.cursor,\n }\n\n return (\n <Motion\n className={cx(\"ui-segmented-control__cursor\", className)}\n layoutDependency={false}\n layoutId=\"cursor\"\n transition={{\n type: \"spring\",\n bounce: 0.15,\n duration: 0.4,\n ...transition,\n }}\n __css={css}\n {...rest}\n />\n )\n}\n"],"mappings":"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","names":["props","ref","value"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yamada-ui/segmented-control",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.15",
|
|
4
4
|
"description": "Yamada UI segmented control components",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"yamada",
|
|
@@ -35,12 +35,12 @@
|
|
|
35
35
|
"url": "https://github.com/hirotomoyamada/yamada-ui/issues"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@yamada-ui/core": "0.15.
|
|
39
|
-
"@yamada-ui/utils": "0.5.
|
|
40
|
-
"@yamada-ui/
|
|
41
|
-
"@yamada-ui/use-
|
|
42
|
-
"@yamada-ui/use-
|
|
43
|
-
"@yamada-ui/use-controllable-state": "0.4.
|
|
38
|
+
"@yamada-ui/core": "0.15.3",
|
|
39
|
+
"@yamada-ui/utils": "0.5.1",
|
|
40
|
+
"@yamada-ui/motion": "0.4.28",
|
|
41
|
+
"@yamada-ui/use-focus-visible": "0.2.9",
|
|
42
|
+
"@yamada-ui/use-descendant": "0.2.11",
|
|
43
|
+
"@yamada-ui/use-controllable-state": "0.4.4"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"react": "^18.0.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/segmented-control.tsx"],"sourcesContent":["import type { CSSUIObject, HTMLUIProps, ThemeProps } from \"@yamada-ui/core\"\nimport {\n ui,\n forwardRef,\n useMultiComponentStyle,\n omitThemeProps,\n} from \"@yamada-ui/core\"\nimport { useControllableState } from \"@yamada-ui/use-controllable-state\"\nimport { createDescendant } from \"@yamada-ui/use-descendant\"\nimport { trackFocusVisible } from \"@yamada-ui/use-focus-visible\"\nimport { useResizeObserver } from \"@yamada-ui/use-resize-observer\"\nimport type { PropGetter, RequiredPropGetter } from \"@yamada-ui/utils\"\nimport {\n ariaAttr,\n createContext,\n cx,\n dataAttr,\n getValidChildren,\n handlerAll,\n mergeRefs,\n omitObject,\n useCallbackRef,\n useIsMounted,\n} from \"@yamada-ui/utils\"\nimport type { ChangeEvent, ChangeEventHandler, ReactElement } from \"react\"\nimport { useCallback, useEffect, useId, useRef, useState } from \"react\"\n\nexport type SegmentedControlItem = SegmentedControlButtonProps & {\n label?: string\n}\n\nconst { DescendantsContextProvider, useDescendants, useDescendant } =\n createDescendant<HTMLButtonElement>()\n\ntype SegmentedControlContext = {\n getInputProps: RequiredPropGetter<{ index: number }>\n getLabelProps: RequiredPropGetter<{ index: number }>\n styles: Record<string, CSSUIObject>\n}\n\nconst [SegmentedControlProvider, useSegmentedControl] =\n createContext<SegmentedControlContext>({\n strict: false,\n name: \"SegmentedControlContext\",\n })\n\ntype SegmentedControlOptions = {\n /**\n * The HTML `name` attribute used for forms.\n */\n name?: string\n /**\n * The value of the segmented control.\n */\n value?: string\n /**\n * The initial value of the segmented control.\n */\n defaultValue?: string\n /**\n * The callback fired when any children radio is checked or unchecked.\n */\n onChange?: (value: string) => void\n /**\n * If `true`, the segmented control will be readonly.\n *\n * @default false\n */\n isReadOnly?: boolean\n /**\n * If `true`, the segmented control will be disabled.\n *\n * @default false\n */\n isDisabled?: boolean\n /**\n * If provided, generate segmented control buttons but based on items.\n *\n * @default '[]'\n */\n items?: SegmentedControlItem[]\n}\n\nexport type SegmentedControlProps = Omit<HTMLUIProps<\"div\">, \"onChange\"> &\n ThemeProps<\"SegmentedControl\"> &\n SegmentedControlOptions\n\nexport const SegmentedControl = forwardRef<SegmentedControlProps, \"div\">(\n (props, ref) => {\n const [styles, mergedProps] = useMultiComponentStyle(\n \"SegmentedControl\",\n props,\n )\n let {\n className,\n id,\n name,\n isReadOnly,\n isDisabled,\n children,\n items = [],\n ...rest\n } = omitThemeProps(mergedProps)\n const isMountedRef = useIsMounted()\n\n id ??= useId()\n name ??= `segmented-control-${useId()}`\n\n rest.onChange = useCallbackRef(rest.onChange)\n\n const descendants = useDescendants()\n\n const [focusedIndex, setFocusedIndex] = useState<number>(-1)\n const [isFocusVisible, setIsFocusVisible] = useState<boolean>(false)\n const [observerRef, containerRect] = useResizeObserver()\n const containerRef = useRef<HTMLDivElement>(null)\n const labelRefs = useRef<Map<string | number, HTMLLabelElement>>(new Map())\n\n const [value, setValue] = useControllableState({\n value: rest.value,\n defaultValue: rest.defaultValue,\n onChange: rest.onChange,\n })\n\n const getActivePosition = useCallback(() => {\n const rect = { width: 0, height: 0, x: 0, y: 0 }\n\n const el = labelRefs.current.get(value)\n\n if (!el || !containerRef.current || !observerRef.current) return rect\n\n const { paddingLeft, paddingTop } = getComputedStyle(containerRef.current)\n\n const gutterX = parseFloat(paddingLeft) || 0\n const gutterY = parseFloat(paddingTop) || 0\n\n let { width, height } = el.getBoundingClientRect()\n rect.x = el.offsetLeft - gutterX\n rect.y = el.offsetTop - gutterY\n\n rect.width = width * (el.offsetWidth / width) || 0\n rect.height = height * (el.offsetWidth / width) || 0\n\n return rect\n }, [observerRef, value])\n\n const [activePosition, setActivePosition] = useState(getActivePosition)\n\n const onChange = useCallback(\n (ev: ChangeEvent<HTMLInputElement>) => {\n if (isDisabled || isReadOnly) {\n ev.preventDefault()\n\n return\n }\n\n setValue(ev.target.value)\n },\n [isDisabled, isReadOnly, setValue],\n )\n\n const onFocus = useCallback(\n (index: number, skip: boolean) => {\n if (isDisabled) return\n\n if (skip) {\n const next = descendants.enabledNextValue(index)\n\n if (next) setFocusedIndex(next.index)\n } else {\n setFocusedIndex(index)\n }\n },\n [descendants, isDisabled],\n )\n\n const onBlur = useCallback(() => setFocusedIndex(-1), [])\n\n const getContainerProps: PropGetter = useCallback(\n (props = {}, ref = null) => ({\n ...omitObject(rest, [\"value\", \"defaultValue\", \"onChange\"]),\n ...props,\n ref: mergeRefs(containerRef, observerRef, ref),\n id,\n \"aria-disabled\": ariaAttr(isDisabled),\n \"aria-readonly\": ariaAttr(isReadOnly),\n onBlur: handlerAll(props.onBlur, onBlur),\n }),\n [id, isDisabled, isReadOnly, observerRef, onBlur, rest],\n )\n\n const getActiveProps: PropGetter = useCallback(\n (props = {}, ref = null) => {\n const { width, height, x, y } = activePosition\n\n return {\n ...props,\n ref,\n style: {\n position: \"absolute\",\n zIndex: 1,\n width,\n height,\n transform: `translate(${x}px, ${y}px)`,\n },\n }\n },\n [activePosition],\n )\n\n const getInputProps: RequiredPropGetter<{ index: number }> = useCallback(\n ({ index, ...props } = {}, ref = null) => {\n const disabled = props.disabled ?? props.isDisabled ?? isDisabled\n const readOnly = props.readOnly ?? props.isReadOnly ?? isReadOnly\n const checked = props.value === value\n\n return {\n ...omitObject(props, [\"isDisabled\", \"isReadOnly\"]),\n ref,\n id: `${id}-${index}`,\n type: \"radio\",\n name,\n disabled: disabled || readOnly,\n readOnly,\n checked,\n \"aria-disabled\": ariaAttr(disabled),\n \"aria-readonly\": ariaAttr(readOnly),\n \"data-checked\": dataAttr(checked),\n \"data-focus\": dataAttr(index === focusedIndex),\n style: {\n border: \"0px\",\n clip: \"rect(0px, 0px, 0px, 0px)\",\n height: \"1px\",\n width: \"1px\",\n margin: \"-1px\",\n padding: \"0px\",\n overflow: \"hidden\",\n whiteSpace: \"nowrap\",\n position: \"absolute\",\n },\n onChange: handlerAll(props.onChange, (ev) =>\n !disabled && !readOnly\n ? onChange(ev as ChangeEvent<HTMLInputElement>)\n : {},\n ),\n }\n },\n [isDisabled, isReadOnly, value, id, name, focusedIndex, onChange],\n )\n\n const getLabelProps: RequiredPropGetter<{ index: number }> = useCallback(\n ({ index, ...props } = {}, ref = null) => {\n const disabled = props.disabled ?? props.isDisabled ?? isDisabled\n const readOnly = props.readOnly ?? props.isReadOnly ?? isReadOnly\n const checked = props.value === value\n const focused = index === focusedIndex\n\n return {\n props,\n ref: mergeRefs(\n (node) => labelRefs.current.set(props.value, node),\n ref,\n ),\n \"aria-disabled\": ariaAttr(disabled),\n \"aria-readonly\": ariaAttr(readOnly),\n \"data-checked\": dataAttr(checked),\n \"data-focus\": dataAttr(focused),\n \"data-focus-visible\": dataAttr(focused && isFocusVisible),\n onFocus: handlerAll(props.onFocus, () =>\n onFocus(index, disabled || readOnly),\n ),\n ...(disabled || readOnly\n ? {\n _hover: {},\n _active: {},\n _focus: {},\n _invalid: {},\n _focusVisible: {},\n }\n : {}),\n style: { position: \"relative\", zIndex: 2 },\n }\n },\n [focusedIndex, isDisabled, isFocusVisible, isReadOnly, onFocus, value],\n )\n\n useEffect(() => {\n return trackFocusVisible(setIsFocusVisible)\n }, [])\n\n useEffect(() => {\n setActivePosition(getActivePosition())\n }, [focusedIndex, containerRect, value, getActivePosition])\n\n const css: CSSUIObject = {\n position: \"relative\",\n display: \"inline-flex\",\n alignItems: \"center\",\n ...styles.container,\n }\n\n const validChildren = getValidChildren(children)\n let computedChildren: ReactElement[] = []\n\n if (!validChildren.length && items.length) {\n computedChildren = items.map(({ label, value, ...props }, i) => (\n <SegmentedControlButton key={i} value={value} {...props}>\n {label}\n </SegmentedControlButton>\n ))\n } else {\n computedChildren = validChildren\n }\n\n if (value == null && rest.defaultValue == null) {\n for (const child of computedChildren) {\n if (child.type !== SegmentedControlButton) continue\n\n const value = child.props.value\n\n setValue(value)\n\n break\n }\n }\n\n return (\n <DescendantsContextProvider value={descendants}>\n <SegmentedControlProvider\n value={{ getInputProps, getLabelProps, styles }}\n >\n <ui.div\n {...getContainerProps({}, ref)}\n className={cx(\"ui-segmented-control\", className)}\n __css={css}\n >\n {isMountedRef.current ? (\n <ui.span\n className=\"ui-segmented-control__active\"\n {...getActiveProps()}\n __css={styles.active}\n />\n ) : null}\n\n {computedChildren}\n </ui.div>\n </SegmentedControlProvider>\n </DescendantsContextProvider>\n )\n },\n)\n\ntype SegmentedControlButtonOptions = {\n /**\n * The value of the segmented control button.\n */\n value: string | number\n /**\n * The callback fired when any children radio is checked or unchecked.\n */\n onChange?: ChangeEventHandler<HTMLInputElement>\n}\n\nexport type SegmentedControlButtonProps = Omit<\n HTMLUIProps<\"label\">,\n \"onChange\"\n> &\n Pick<SegmentedControlProps, \"isDisabled\" | \"isReadOnly\"> &\n SegmentedControlButtonOptions\n\nexport const SegmentedControlButton = forwardRef<\n SegmentedControlButtonProps,\n \"input\"\n>(\n (\n {\n className,\n disabled,\n readOnly,\n isDisabled,\n isReadOnly,\n value,\n onChange,\n children,\n ...rest\n },\n ref,\n ) => {\n const { getInputProps, getLabelProps, styles } = useSegmentedControl()\n\n const { index, register } = useDescendant({\n disabled: isDisabled || isReadOnly,\n })\n\n const props = {\n index,\n value,\n onChange,\n disabled,\n readOnly,\n isDisabled,\n isReadOnly,\n }\n\n const css: CSSUIObject = {\n cursor: \"pointer\",\n flex: \"1 1 0%\",\n display: \"inline-flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n ...styles.button,\n }\n\n return (\n <ui.label\n {...getLabelProps(omitObject(props, [\"onChange\"]))}\n className={cx(\"ui-segmented-control__button\", className)}\n __css={css}\n {...rest}\n >\n <ui.input {...getInputProps(props, mergeRefs(register, ref))} />\n <ui.span>{children}</ui.span>\n </ui.label>\n )\n },\n)\n"],"mappings":"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","names":["props","ref","value"]}
|