@dashfoo/react 0.6.1 → 0.6.3

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.js CHANGED
@@ -854,6 +854,39 @@ const DragProvider = ({ children, onCommit, splitDock }) => {
854
854
  const FloatLayerContext = createContext(false);
855
855
  const useHasFloatLayer = () => useContext(FloatLayerContext);
856
856
 
857
+ //#endregion
858
+ //#region src/hooks/use-inline-rename.ts
859
+ const useInlineRename = ({ currentName, inputRef, onCommit, onDone }) => {
860
+ const done = useRef(false);
861
+ useEffect(() => {
862
+ inputRef.current?.focus();
863
+ inputRef.current?.select();
864
+ }, [inputRef]);
865
+ const commit = (value) => {
866
+ const trimmed = value.trim();
867
+ if (trimmed && trimmed !== currentName) onCommit(trimmed);
868
+ onDone();
869
+ };
870
+ const handleKeyDown = (event) => {
871
+ if (event.key === "Enter") {
872
+ done.current = true;
873
+ commit(event.currentTarget.value);
874
+ } else if (event.key === "Escape") {
875
+ done.current = true;
876
+ onDone();
877
+ }
878
+ };
879
+ const handleBlur = (event) => {
880
+ if (done.current) return;
881
+ done.current = true;
882
+ commit(event.currentTarget.value);
883
+ };
884
+ return {
885
+ handleBlur,
886
+ handleKeyDown
887
+ };
888
+ };
889
+
857
890
  //#endregion
858
891
  //#region src/lib/float-geometry.ts
859
892
  const MIN_WIDTH = 200;
@@ -1686,28 +1719,21 @@ const RenameEditor = ({ defaultValue, onBlur, onKeyDown, ref: userRef, ...props
1686
1719
  const { tab } = useTab();
1687
1720
  const cancelRename = useTabset((state) => state.cancelRename);
1688
1721
  const commitRename = useTabset((state) => state.commitRename);
1689
- const ref = useRef(null);
1690
- const done = useRef(false);
1691
- const refCallback = useMemo(() => mergeRefs(ref, userRef), [userRef]);
1692
- useEffect(() => {
1693
- ref.current?.focus();
1694
- ref.current?.select();
1695
- }, []);
1722
+ const inputRef = useRef(null);
1723
+ const rename = useInlineRename({
1724
+ currentName: tab.name,
1725
+ inputRef,
1726
+ onCommit: (name) => commitRename(tab.id, name),
1727
+ onDone: cancelRename
1728
+ });
1729
+ const refCallback = useMemo(() => mergeRefs(inputRef, userRef), [userRef]);
1696
1730
  const handleKeyDown = (event) => {
1697
1731
  onKeyDown?.(event);
1698
- if (event.key === "Enter") {
1699
- done.current = true;
1700
- commitRename(tab.id, event.currentTarget.value);
1701
- } else if (event.key === "Escape") {
1702
- done.current = true;
1703
- cancelRename();
1704
- }
1732
+ rename.handleKeyDown(event);
1705
1733
  };
1706
1734
  const handleCommitOnBlur = (event) => {
1707
1735
  onBlur?.(event);
1708
- if (done.current) return;
1709
- done.current = true;
1710
- commitRename(tab.id, event.currentTarget.value);
1736
+ rename.handleBlur(event);
1711
1737
  };
1712
1738
  return /* @__PURE__ */ jsx("input", {
1713
1739
  "aria-label": `Rename ${tab.name}`,
@@ -1977,7 +2003,6 @@ const RowView = ({ node, renderTabset }) => {
1977
2003
  const orientation = node.orientation === "row" ? "horizontal" : "vertical";
1978
2004
  const total = node.children.reduce((sum, child) => sum + (child.weight ?? 1), 0);
1979
2005
  const desiredLayout = useMemo(() => layoutFromWeights(node.children, total), [node.children, total]);
1980
- const measured = useRef(false);
1981
2006
  const groupRef = useRef(null);
1982
2007
  const groupElement = useRef(null);
1983
2008
  const syncing = useRef(false);
@@ -2031,11 +2056,8 @@ const RowView = ({ node, renderTabset }) => {
2031
2056
  group.setLayout(target);
2032
2057
  snapping.current = false;
2033
2058
  };
2034
- const handleLayoutChanged = (layout) => {
2035
- if (!measured.current) {
2036
- measured.current = true;
2037
- return;
2038
- }
2059
+ const handleLayoutChanged = (layout, meta) => {
2060
+ if (!meta.isUserInteraction) return;
2039
2061
  if (syncing.current) return;
2040
2062
  const boundary = activeBoundary.current;
2041
2063
  activeBoundary.current = null;
@@ -2123,35 +2145,17 @@ const CHIP_SIZE = {
2123
2145
  };
2124
2146
  const TAP_SLOP = 4;
2125
2147
  const FloatTitleEditor = ({ dispatch, node, onDone }) => {
2126
- const ref = useRef(null);
2127
- const done = useRef(false);
2128
- useEffect(() => {
2129
- ref.current?.focus();
2130
- ref.current?.select();
2131
- }, []);
2132
- const commit = (value) => {
2133
- const trimmed = value.trim();
2134
- if (trimmed && trimmed !== floatTitle(node)) dispatch({
2148
+ const inputRef = useRef(null);
2149
+ const { handleBlur, handleKeyDown } = useInlineRename({
2150
+ currentName: floatTitle(node),
2151
+ inputRef,
2152
+ onCommit: (name) => dispatch({
2135
2153
  floatId: node.id,
2136
- name: trimmed,
2154
+ name,
2137
2155
  type: "renameFloat"
2138
- });
2139
- onDone();
2140
- };
2141
- const handleKeyDown = (event) => {
2142
- if (event.key === "Enter") {
2143
- done.current = true;
2144
- commit(event.currentTarget.value);
2145
- } else if (event.key === "Escape") {
2146
- done.current = true;
2147
- onDone();
2148
- }
2149
- };
2150
- const handleBlur = (event) => {
2151
- if (done.current) return;
2152
- done.current = true;
2153
- commit(event.currentTarget.value);
2154
- };
2156
+ }),
2157
+ onDone
2158
+ });
2155
2159
  return /* @__PURE__ */ jsx("input", {
2156
2160
  "aria-label": `Rename ${floatTitle(node)}`,
2157
2161
  "data-dashfoo": "float-rename",
@@ -2159,7 +2163,7 @@ const FloatTitleEditor = ({ dispatch, node, onDone }) => {
2159
2163
  onBlur: handleBlur,
2160
2164
  onKeyDown: handleKeyDown,
2161
2165
  onPointerDown: (event) => event.stopPropagation(),
2162
- ref,
2166
+ ref: inputRef,
2163
2167
  style: titleStyle,
2164
2168
  type: "text"
2165
2169
  });
@@ -2562,12 +2566,11 @@ const DashfooLayout = forwardRef((props, ref) => {
2562
2566
  responsive?.orientation,
2563
2567
  store.model
2564
2568
  ]);
2565
- const isCompactRef = useRef(isCompact);
2566
- isCompactRef.current = isCompact;
2569
+ const storeDispatch = store.dispatch;
2567
2570
  const dispatch = useCallback((action) => {
2568
- if (isCompactRef.current && action.type === "adjustSplit") return;
2569
- store.dispatch(action);
2570
- }, [store]);
2571
+ if (isCompact && action.type === "adjustSplit") return;
2572
+ storeDispatch(action);
2573
+ }, [isCompact, storeDispatch]);
2571
2574
  const maximized = view.maximizedTabsetId ? findTabset(view, view.maximizedTabsetId) : void 0;
2572
2575
  const tree = /* @__PURE__ */ jsx(Layout.FloatLayer, {
2573
2576
  floats: store.model.floats ?? [],