@yamada-ui/segmented-control 0.4.13 → 0.4.14

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.
@@ -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 [value, setValue] = useControllableState({
60
- value: rest.value,
61
- defaultValue: rest.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
- setValue(ev.target.value);
70
+ setSelectedValue(ev.target.value);
87
71
  },
88
- [isDisabled, isReadOnly, setValue]
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, ["value", "defaultValue", "onChange"]),
91
+ ...omitObject(rest, ["onChange"]),
108
92
  ...props2,
109
- ref: mergeRefs(containerRef, observerRef, ref2),
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, observerRef, onBlur, rest]
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 === 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, value, id, name, focusedIndex, onChange]
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 === 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
- [focusedIndex, isDisabled, isFocusVisible, isReadOnly, onFocus, value]
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 (value == null && rest.defaultValue == null) {
195
+ if (selectedValue == null && defaultValue == null) {
226
196
  for (const child of computedChildren) {
227
- if (child.type !== SegmentedControlButton)
228
- continue;
197
+ if (child.type !== SegmentedControlButton) {
198
+ if (child.type.displayName !== SegmentedControlButton.displayName)
199
+ continue;
200
+ }
229
201
  const value2 = child.props.value;
230
- setValue(value2);
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__ */ jsxs(
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 { getInputProps, getLabelProps, styles } = useSegmentedControl();
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-LCPXOL6W.mjs.map
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
@@ -1,3 +1,4 @@
1
1
  export { SegmentedControl, SegmentedControlButton, SegmentedControlButtonProps, SegmentedControlItem, SegmentedControlProps } from './segmented-control.mjs';
2
2
  import '@yamada-ui/core';
3
+ import '@yamada-ui/motion';
3
4
  import 'react';
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export { SegmentedControl, SegmentedControlButton, SegmentedControlButtonProps, SegmentedControlItem, SegmentedControlProps } from './segmented-control.js';
2
2
  import '@yamada-ui/core';
3
+ import '@yamada-ui/motion';
3
4
  import 'react';
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 [value, setValue] = (0, import_use_controllable_state.useControllableState)({
70
- value: rest.value,
71
- defaultValue: rest.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
- setValue(ev.target.value);
80
+ setSelectedValue(ev.target.value);
97
81
  },
98
- [isDisabled, isReadOnly, setValue]
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, ["value", "defaultValue", "onChange"]),
101
+ ...(0, import_utils.omitObject)(rest, ["onChange"]),
118
102
  ...props2,
119
- ref: (0, import_utils.mergeRefs)(containerRef, observerRef, ref2),
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, observerRef, onBlur, rest]
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 === 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, value, id, name, focusedIndex, onChange]
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 === 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
- [focusedIndex, isDisabled, isFocusVisible, isReadOnly, onFocus, value]
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 (value == null && rest.defaultValue == null) {
205
+ if (selectedValue == null && defaultValue == null) {
236
206
  for (const child of computedChildren) {
237
- if (child.type !== SegmentedControlButton)
238
- continue;
207
+ if (child.type !== SegmentedControlButton) {
208
+ if (child.type.displayName !== SegmentedControlButton.displayName)
209
+ continue;
210
+ }
239
211
  const value2 = child.props.value;
240
- setValue(value2);
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.jsxs)(
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 { getInputProps, getLabelProps, styles } = useSegmentedControl();
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":"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","names":["props","ref","value"]}
package/dist/index.mjs CHANGED
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  SegmentedControl,
4
4
  SegmentedControlButton
5
- } from "./chunk-LCPXOL6W.mjs";
5
+ } from "./chunk-DXWQZMEU.mjs";
6
6
  export {
7
7
  SegmentedControl,
8
8
  SegmentedControlButton
@@ -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 [value, setValue] = (0, import_use_controllable_state.useControllableState)({
68
- value: rest.value,
69
- defaultValue: rest.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
- setValue(ev.target.value);
78
+ setSelectedValue(ev.target.value);
95
79
  },
96
- [isDisabled, isReadOnly, setValue]
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, ["value", "defaultValue", "onChange"]),
99
+ ...(0, import_utils.omitObject)(rest, ["onChange"]),
116
100
  ...props2,
117
- ref: (0, import_utils.mergeRefs)(containerRef, observerRef, ref2),
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, observerRef, onBlur, rest]
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 === 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, value, id, name, focusedIndex, onChange]
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 === 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
- [focusedIndex, isDisabled, isFocusVisible, isReadOnly, onFocus, value]
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 (value == null && rest.defaultValue == null) {
203
+ if (selectedValue == null && defaultValue == null) {
234
204
  for (const child of computedChildren) {
235
- if (child.type !== SegmentedControlButton)
236
- continue;
205
+ if (child.type !== SegmentedControlButton) {
206
+ if (child.type.displayName !== SegmentedControlButton.displayName)
207
+ continue;
208
+ }
237
209
  const value2 = child.props.value;
238
- setValue(value2);
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.jsxs)(
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 { getInputProps, getLabelProps, styles } = useSegmentedControl();
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"]}
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  SegmentedControl,
4
4
  SegmentedControlButton
5
- } from "./chunk-LCPXOL6W.mjs";
5
+ } from "./chunk-DXWQZMEU.mjs";
6
6
  export {
7
7
  SegmentedControl,
8
8
  SegmentedControlButton
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yamada-ui/segmented-control",
3
- "version": "0.4.13",
3
+ "version": "0.4.14",
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.1",
39
- "@yamada-ui/utils": "0.5.0",
40
- "@yamada-ui/use-focus-visible": "0.2.8",
41
- "@yamada-ui/use-descendant": "0.2.10",
42
- "@yamada-ui/use-resize-observer": "0.2.8",
43
- "@yamada-ui/use-controllable-state": "0.4.3"
38
+ "@yamada-ui/core": "0.15.2",
39
+ "@yamada-ui/utils": "0.5.1",
40
+ "@yamada-ui/motion": "0.4.27",
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"]}