@mirror-physics/fractal-ui 0.2.0-next.18 → 0.2.0-next.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -944,7 +944,22 @@ function Tabs({
944
944
  );
945
945
  const isControlled = controlledValue !== void 0;
946
946
  const activeId = isControlled ? controlledValue : internalValue;
947
+ const tabListRef = (0, import_react3.useRef)(null);
947
948
  const tabRefs = (0, import_react3.useRef)({});
949
+ const [indicator, setIndicator] = (0, import_react3.useState)(null);
950
+ (0, import_react3.useLayoutEffect)(() => {
951
+ const updateIndicator = () => {
952
+ const activeTab = tabRefs.current[activeId];
953
+ if (!activeTab) return;
954
+ setIndicator({ offset: activeTab.offsetLeft, width: activeTab.offsetWidth });
955
+ };
956
+ updateIndicator();
957
+ const list = tabListRef.current;
958
+ if (!list || typeof ResizeObserver === "undefined") return;
959
+ const observer = new ResizeObserver(updateIndicator);
960
+ observer.observe(list);
961
+ return () => observer.disconnect();
962
+ }, [activeId, items.length]);
948
963
  const selectTab = (id) => {
949
964
  if (isControlled) {
950
965
  onValueChange?.(id);
@@ -954,6 +969,10 @@ function Tabs({
954
969
  }
955
970
  };
956
971
  const focusable = items.filter((i) => !i.disabled);
972
+ const indicatorStyle = indicator ? {
973
+ "--fractal-tabs-indicator-offset": `${indicator.offset}px`,
974
+ "--fractal-tabs-indicator-width": `${indicator.width}px`
975
+ } : void 0;
957
976
  const onKeyDown = (event) => {
958
977
  const currentIndex = focusable.findIndex((i) => i.id === activeId);
959
978
  if (currentIndex === -1) return;
@@ -980,35 +999,46 @@ function Tabs({
980
999
  requestAnimationFrame(() => tabRefs.current[nextId2]?.focus());
981
1000
  };
982
1001
  return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: cn("fractal-tabs", className), children: [
983
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { role: "tablist", "aria-label": ariaLabel, className: "fractal-tabs-list", children: items.map((item) => {
984
- const isActive = item.id === activeId;
985
- const tabId = `${reactId}-tab-${item.id}`;
986
- const panelId = `${reactId}-panel-${item.id}`;
987
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
988
- "button",
989
- {
990
- ref: (el) => {
991
- tabRefs.current[item.id] = el;
992
- },
993
- id: tabId,
994
- role: "tab",
995
- type: "button",
996
- "aria-selected": isActive,
997
- "aria-controls": panelId,
998
- tabIndex: isActive ? 0 : -1,
999
- disabled: item.disabled,
1000
- className: cn(
1001
- "fractal-tabs-trigger",
1002
- isActive && "fractal-tabs-trigger--active",
1003
- item.disabled && "fractal-tabs-trigger--disabled"
1004
- ),
1005
- onClick: () => !item.disabled && selectTab(item.id),
1006
- onKeyDown,
1007
- children: item.label
1008
- },
1009
- item.id
1010
- );
1011
- }) }),
1002
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1003
+ "div",
1004
+ {
1005
+ ref: tabListRef,
1006
+ role: "tablist",
1007
+ "aria-label": ariaLabel,
1008
+ className: "fractal-tabs-list",
1009
+ "data-indicator-ready": indicator ? "true" : void 0,
1010
+ style: indicatorStyle,
1011
+ children: items.map((item) => {
1012
+ const isActive = item.id === activeId;
1013
+ const tabId = `${reactId}-tab-${item.id}`;
1014
+ const panelId = `${reactId}-panel-${item.id}`;
1015
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1016
+ "button",
1017
+ {
1018
+ ref: (el) => {
1019
+ tabRefs.current[item.id] = el;
1020
+ },
1021
+ id: tabId,
1022
+ role: "tab",
1023
+ type: "button",
1024
+ "aria-selected": isActive,
1025
+ "aria-controls": panelId,
1026
+ tabIndex: isActive ? 0 : -1,
1027
+ disabled: item.disabled,
1028
+ className: cn(
1029
+ "fractal-tabs-trigger",
1030
+ isActive && "fractal-tabs-trigger--active",
1031
+ item.disabled && "fractal-tabs-trigger--disabled"
1032
+ ),
1033
+ onClick: () => !item.disabled && selectTab(item.id),
1034
+ onKeyDown,
1035
+ children: item.label
1036
+ },
1037
+ item.id
1038
+ );
1039
+ })
1040
+ }
1041
+ ),
1012
1042
  items.map((item) => {
1013
1043
  const tabId = `${reactId}-tab-${item.id}`;
1014
1044
  const panelId = `${reactId}-panel-${item.id}`;