Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@featherds/dock

Package Overview
Dependencies
Maintainers
6
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@featherds/dock - npm Package Compare versions

Comparing version
0.12.42
to
0.12.43
+84
-27
dist/index.mjs

@@ -7,2 +7,3 @@ import { defineComponent, useCssVars, computed, ref, watch, provide, inject, readonly, onMounted, onUnmounted, createBlock, openBlock, resolveDynamicComponent, normalizeClass, withCtx, createVNode, createElementVNode, unref, renderSlot, createTextVNode } from "vue";

const _hoisted_1 = ["id", "aria-label"];
const _hoisted_2 = { class: "feather-dock-resizer" };
const _sfc_main = /* @__PURE__ */ defineComponent({

@@ -26,8 +27,9 @@ __name: "FeatherDock",

"update:dock-expanded",
"update:dock-collapsed"
"update:dock-collapsed",
"update:dock-resized"
],
setup(__props, { emit: __emit }) {
useCssVars((_ctx) => ({
"13ea2f12": dockWidth.value,
"f3bd3be2": dockConfig.value.isOpen ? "cubic-bezier(0, 0.8, 0.4, 1)" : "cubic-beziercubic-bezier(0, 0.8, 0.4, 1)"
"aa306c3a": dockWidth.value,
"26049220": dockConfig.value.isOpen ? "cubic-bezier(0, 0.8, 0.4, 1)" : "cubic-beziercubic-bezier(0, 0.8, 0.4, 1)"
}));

@@ -45,2 +47,3 @@ const props = __props;

"dock-closed": !isDockOpen.value,
"is-resizing": isResizing.value,
[props.location]: true

@@ -52,7 +55,69 @@ };

location: props.location,
isOpen: isDockOpen.value
isOpen: isDockOpen.value,
isResizing: isResizing.value
}));
const convertToPixels = (value) => {
if (!value) return "0";
if (typeof value === "number") return value;
if (value.endsWith("px")) return parseInt(value, 10).toString();
const el = document.createElement("div");
el.style.position = "absolute";
el.style.visibility = "hidden";
el.style.width = value;
document.body.appendChild(el);
const pixels = el.getBoundingClientRect().width;
document.body.removeChild(el);
return pixels.toString();
};
const expandedWidthPx = computed(() => {
return `${convertToPixels(props.expandedWidth)}px`;
});
const collapsedWidthPx = computed(() => {
return `${convertToPixels(props.collapsedWidth)}px`;
});
const currentExpandedWidth = ref(expandedWidthPx.value);
const dockWidth = computed(() => {
return dockConfig.value.isOpen ? props.expandedWidth : props.collapsedWidth;
return dockConfig.value.isOpen ? currentExpandedWidth.value : props.collapsedWidth;
});
const isResizing = ref(false);
const startX = ref(0);
const startWidthPx = ref(0);
watch(
() => props.expandedWidth,
() => {
currentExpandedWidth.value = expandedWidthPx.value;
}
);
const onResizerDown = (event) => {
if (event.isPrimary === false) return;
event.preventDefault();
isResizing.value = true;
startX.value = event.clientX;
startWidthPx.value = parseInt(currentExpandedWidth.value, 10) || 0;
window.addEventListener("pointermove", onResizerMove);
window.addEventListener("pointerup", onResizerUp);
};
const onResizerMove = (event) => {
if (!isResizing.value) return;
const clientX = event.clientX;
const delta = clientX - startX.value;
let newWidth = startWidthPx.value;
if (props.location === "left") {
newWidth = startWidthPx.value + delta;
} else {
newWidth = startWidthPx.value - delta;
}
const minWidth = parseInt(convertToPixels(props.collapsedWidth), 10) || 48;
const maxWidth = Math.max(200, window.innerWidth - 64);
newWidth = Math.max(minWidth, Math.min(maxWidth, newWidth));
currentExpandedWidth.value = `${Math.round(newWidth)}px`;
updatePushedElement();
};
const onResizerUp = () => {
if (!isResizing.value) return;
isResizing.value = false;
window.removeEventListener("pointermove", onResizerMove);
window.removeEventListener("pointerup", onResizerUp);
emit("update:dock-resized", currentExpandedWidth.value);
};
const toggleDock = () => {

@@ -78,21 +143,2 @@ isDockOpen.value = !isDockOpen.value;

};
const convertToPixels = (value) => {
if (!value) return "0";
if (typeof value === "number") return value;
if (value.endsWith("px")) return parseInt(value, 10).toString();
const el = document.createElement("div");
el.style.position = "absolute";
el.style.visibility = "hidden";
el.style.width = value;
document.body.appendChild(el);
const pixels = el.getBoundingClientRect().width;
document.body.removeChild(el);
return pixels.toString();
};
const expandedWidthPx = computed(() => {
return `${convertToPixels(props.expandedWidth)}px`;
});
const collapsedWidthPx = computed(() => {
return `${convertToPixels(props.collapsedWidth)}px`;
});
const updatePushedElement = () => {

@@ -113,3 +159,3 @@ if (!props.pushedSelector) return;

const isInFlow = position === "static" || position === "relative";
const widthFromProps = dockConfig.value.isOpen ? `${parseInt(convertToPixels(props.expandedWidth)) + parseInt(convertToPixels(pushedSelectorPadding.value))}px` : `${parseInt(convertToPixels(props.collapsedWidth)) + parseInt(convertToPixels(pushedSelectorPadding.value))}px`;
const widthFromProps = dockConfig.value.isOpen ? `${parseInt(convertToPixels(currentExpandedWidth.value)) + parseInt(convertToPixels(pushedSelectorPadding.value))}px` : `${parseInt(convertToPixels(props.collapsedWidth)) + parseInt(convertToPixels(pushedSelectorPadding.value))}px`;
const widthInPx = dockConfig.value.isOpen ? expandedWidthPx.value : collapsedWidthPx.value;

@@ -183,2 +229,7 @@ if (isInFlow) {

onUnmounted(() => {
if (isResizing.value) {
window.removeEventListener("pointermove", onResizerMove);
window.removeEventListener("pointerup", onResizerUp);
isResizing.value = false;
}
document.removeEventListener("keydown", handleSidebarEscape);

@@ -260,3 +311,9 @@ if (props.pushedSelector) {

], true)
], 8, _hoisted_1)
], 8, _hoisted_1),
createElementVNode("div", _hoisted_2, [
createElementVNode("div", {
class: "feather-dock-resizer-handle",
onPointerdown: onResizerDown
}, null, 32)
])
]),

@@ -275,5 +332,5 @@ _: 3

};
const FeatherDock = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-4407d75f"]]);
const FeatherDock = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-cd4a218e"]]);
export {
FeatherDock
};

@@ -18,2 +18,3 @@

--feather-dock-header-offset: 0px;
--feather-dock-resizer-width: 0.5rem;
@media (prefers-reduced-motion: reduce) {

@@ -32,5 +33,5 @@ --feather-dock-timing: 0.1s; /* nearly instant */

}
.feather-dock[data-v-4407d75f] {
--feather-dock-width: var(--13ea2f12);
--feather-dock-toggle-timing-fn: var(--f3bd3be2);
.feather-dock[data-v-cd4a218e] {
--feather-dock-width: var(--aa306c3a);
--feather-dock-toggle-timing-fn: var(--26049220);
position: fixed;

@@ -53,6 +54,6 @@ inset: var(--feather-dock-header-offset) 0 0 0;

}
.feather-dock.right[data-v-4407d75f] {
.feather-dock.right[data-v-cd4a218e] {
inset: 0 0 0 auto;
}
.feather-dock.right .feather-dock-toggle[data-v-4407d75f] {
.feather-dock.right .feather-dock-toggle[data-v-cd4a218e] {
transform: rotate(180deg);

@@ -64,7 +65,7 @@ right: calc(var(--feather-dock-width) - 1rem);

}
.feather-dock.dock-closed[data-v-4407d75f] {
.feather-dock.dock-closed[data-v-cd4a218e] {
scrollbar-width: none;
scrollbar-color: transparent transparent;
}
.feather-dock.dock-closed > .feather-dock-toggle[data-v-4407d75f] {
.feather-dock.dock-closed > .feather-dock-toggle[data-v-cd4a218e] {
position: absolute;

@@ -74,6 +75,6 @@ left: calc(var(--feather-dock-width) / 2 - 1.5rem);

}
.feather-dock.dock-closed > .feather-dock-toggle[data-v-4407d75f] {
.feather-dock.dock-closed > .feather-dock-toggle[data-v-cd4a218e] {
top: var(--feather-dock-toggle-top);
}
.feather-dock > .feather-dock-toggle[data-v-4407d75f] {
.feather-dock > .feather-dock-toggle[data-v-cd4a218e] {
position: fixed;

@@ -92,29 +93,29 @@ top: calc(var(--feather-dock-toggle-top) + var(--feather-dock-header-offset));

}
.feather-dock > .feather-dock-toggle .ripple[data-v-4407d75f] {
.feather-dock > .feather-dock-toggle .ripple[data-v-cd4a218e] {
background-color: var(--feather-state-color-on-neutral);
opacity: var(--feather-state-opacity-pressed-on-neutral);
}
.feather-dock > .feather-dock-toggle.selected[data-v-4407d75f],
.feather-dock > .feather-dock-toggle .selected[data-v-4407d75f] {
.feather-dock > .feather-dock-toggle.selected[data-v-cd4a218e],
.feather-dock > .feather-dock-toggle .selected[data-v-cd4a218e] {
background: linear-gradient(rgba(var(--feather-state-color-on-neutral-r), var(--feather-state-color-on-neutral-g), var(--feather-state-color-on-neutral-b), var(--feather-state-opacity-selected-on-neutral)), rgba(var(--feather-state-color-on-neutral-r), var(--feather-state-color-on-neutral-g), var(--feather-state-color-on-neutral-b), var(--feather-state-opacity-selected-on-neutral))), linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0));
}
.feather-dock > .feather-dock-toggle.hover[data-v-4407d75f]:hover, .feather-dock > .feather-dock-toggle:hover .hover[data-v-4407d75f] {
.feather-dock > .feather-dock-toggle.hover[data-v-cd4a218e]:hover, .feather-dock > .feather-dock-toggle:hover .hover[data-v-cd4a218e] {
background: linear-gradient(rgba(var(--feather-state-color-on-neutral-r), var(--feather-state-color-on-neutral-g), var(--feather-state-color-on-neutral-b), var(--feather-state-opacity-hover-on-neutral)), rgba(var(--feather-state-color-on-neutral-r), var(--feather-state-color-on-neutral-g), var(--feather-state-color-on-neutral-b), var(--feather-state-opacity-hover-on-neutral))), linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0));
}
.feather-dock > .feather-dock-toggle.hover:hover.selected[data-v-4407d75f], .feather-dock > .feather-dock-toggle:hover .hover.selected[data-v-4407d75f] {
.feather-dock > .feather-dock-toggle.hover:hover.selected[data-v-cd4a218e], .feather-dock > .feather-dock-toggle:hover .hover.selected[data-v-cd4a218e] {
background: linear-gradient(rgba(var(--feather-state-color-on-neutral-r), var(--feather-state-color-on-neutral-g), var(--feather-state-color-on-neutral-b), var(--feather-state-opacity-selected-on-neutral)), rgba(var(--feather-state-color-on-neutral-r), var(--feather-state-color-on-neutral-g), var(--feather-state-color-on-neutral-b), var(--feather-state-opacity-selected-on-neutral))), linear-gradient(rgba(var(--feather-state-color-on-neutral-r), var(--feather-state-color-on-neutral-g), var(--feather-state-color-on-neutral-b), var(--feather-state-opacity-hover-on-neutral)), rgba(var(--feather-state-color-on-neutral-r), var(--feather-state-color-on-neutral-g), var(--feather-state-color-on-neutral-b), var(--feather-state-opacity-hover-on-neutral))), linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0));
}
.feather-dock > .feather-dock-toggle:focus.focus[data-v-4407d75f], .feather-dock > .feather-dock-toggle:focus .focus[data-v-4407d75f], .feather-dock > .feather-dock-toggle.focused.focus[data-v-4407d75f], .feather-dock > .feather-dock-toggle.focused .focus[data-v-4407d75f] {
.feather-dock > .feather-dock-toggle:focus.focus[data-v-cd4a218e], .feather-dock > .feather-dock-toggle:focus .focus[data-v-cd4a218e], .feather-dock > .feather-dock-toggle.focused.focus[data-v-cd4a218e], .feather-dock > .feather-dock-toggle.focused .focus[data-v-cd4a218e] {
background: linear-gradient(rgba(var(--feather-state-color-on-neutral-r), var(--feather-state-color-on-neutral-g), var(--feather-state-color-on-neutral-b), var(--feather-state-opacity-focus-on-neutral)), rgba(var(--feather-state-color-on-neutral-r), var(--feather-state-color-on-neutral-g), var(--feather-state-color-on-neutral-b), var(--feather-state-opacity-focus-on-neutral))), linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0));
}
.feather-dock > .feather-dock-toggle:focus.focus.selected[data-v-4407d75f], .feather-dock > .feather-dock-toggle:focus .focus.selected[data-v-4407d75f], .feather-dock > .feather-dock-toggle.focused.focus.selected[data-v-4407d75f], .feather-dock > .feather-dock-toggle.focused .focus.selected[data-v-4407d75f] {
.feather-dock > .feather-dock-toggle:focus.focus.selected[data-v-cd4a218e], .feather-dock > .feather-dock-toggle:focus .focus.selected[data-v-cd4a218e], .feather-dock > .feather-dock-toggle.focused.focus.selected[data-v-cd4a218e], .feather-dock > .feather-dock-toggle.focused .focus.selected[data-v-cd4a218e] {
background: linear-gradient(rgba(var(--feather-state-color-on-neutral-r), var(--feather-state-color-on-neutral-g), var(--feather-state-color-on-neutral-b), var(--feather-state-opacity-selected-on-neutral)), rgba(var(--feather-state-color-on-neutral-r), var(--feather-state-color-on-neutral-g), var(--feather-state-color-on-neutral-b), var(--feather-state-opacity-selected-on-neutral))), linear-gradient(rgba(var(--feather-state-color-on-neutral-r), var(--feather-state-color-on-neutral-g), var(--feather-state-color-on-neutral-b), var(--feather-state-opacity-focus-on-neutral)), rgba(var(--feather-state-color-on-neutral-r), var(--feather-state-color-on-neutral-g), var(--feather-state-color-on-neutral-b), var(--feather-state-opacity-focus-on-neutral))), linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0));
}
.feather-dock > .feather-dock-toggle:hover:focus .focus.hover[data-v-4407d75f], .feather-dock > .feather-dock-toggle:hover:focus.focus.hover[data-v-4407d75f], .feather-dock > .feather-dock-toggle:hover.focused .focus.hover[data-v-4407d75f], .feather-dock > .feather-dock-toggle:hover.focused.focus.hover[data-v-4407d75f] {
.feather-dock > .feather-dock-toggle:hover:focus .focus.hover[data-v-cd4a218e], .feather-dock > .feather-dock-toggle:hover:focus.focus.hover[data-v-cd4a218e], .feather-dock > .feather-dock-toggle:hover.focused .focus.hover[data-v-cd4a218e], .feather-dock > .feather-dock-toggle:hover.focused.focus.hover[data-v-cd4a218e] {
background: linear-gradient(rgba(var(--feather-state-color-on-neutral-r), var(--feather-state-color-on-neutral-g), var(--feather-state-color-on-neutral-b), var(--feather-state-opacity-hover-on-neutral)), rgba(var(--feather-state-color-on-neutral-r), var(--feather-state-color-on-neutral-g), var(--feather-state-color-on-neutral-b), var(--feather-state-opacity-hover-on-neutral))), linear-gradient(rgba(var(--feather-state-color-on-neutral-r), var(--feather-state-color-on-neutral-g), var(--feather-state-color-on-neutral-b), var(--feather-state-opacity-focus-on-neutral)), rgba(var(--feather-state-color-on-neutral-r), var(--feather-state-color-on-neutral-g), var(--feather-state-color-on-neutral-b), var(--feather-state-opacity-focus-on-neutral))), linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0));
}
.feather-dock > .feather-dock-toggle:hover:focus .focus.hover.selected[data-v-4407d75f], .feather-dock > .feather-dock-toggle:hover:focus.focus.hover.selected[data-v-4407d75f], .feather-dock > .feather-dock-toggle:hover.focused .focus.hover.selected[data-v-4407d75f], .feather-dock > .feather-dock-toggle:hover.focused.focus.hover.selected[data-v-4407d75f] {
.feather-dock > .feather-dock-toggle:hover:focus .focus.hover.selected[data-v-cd4a218e], .feather-dock > .feather-dock-toggle:hover:focus.focus.hover.selected[data-v-cd4a218e], .feather-dock > .feather-dock-toggle:hover.focused .focus.hover.selected[data-v-cd4a218e], .feather-dock > .feather-dock-toggle:hover.focused.focus.hover.selected[data-v-cd4a218e] {
background: linear-gradient(rgba(var(--feather-state-color-on-neutral-r), var(--feather-state-color-on-neutral-g), var(--feather-state-color-on-neutral-b), var(--feather-state-opacity-selected-on-neutral)), rgba(var(--feather-state-color-on-neutral-r), var(--feather-state-color-on-neutral-g), var(--feather-state-color-on-neutral-b), var(--feather-state-opacity-selected-on-neutral))), linear-gradient(rgba(var(--feather-state-color-on-neutral-r), var(--feather-state-color-on-neutral-g), var(--feather-state-color-on-neutral-b), var(--feather-state-opacity-hover-on-neutral)), rgba(var(--feather-state-color-on-neutral-r), var(--feather-state-color-on-neutral-g), var(--feather-state-color-on-neutral-b), var(--feather-state-opacity-hover-on-neutral))), linear-gradient(rgba(var(--feather-state-color-on-neutral-r), var(--feather-state-color-on-neutral-g), var(--feather-state-color-on-neutral-b), var(--feather-state-opacity-focus-on-neutral)), rgba(var(--feather-state-color-on-neutral-r), var(--feather-state-color-on-neutral-g), var(--feather-state-color-on-neutral-b), var(--feather-state-opacity-focus-on-neutral))), linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0));
}
.feather-dock > .feather-dock-content[data-v-4407d75f] {
.feather-dock > .feather-dock-content[data-v-cd4a218e] {
position: relative;

@@ -128,7 +129,73 @@ height: 100%;

flex-direction: column;
align-items: center;
align-items: flex-start;
}
.feather-dock > .feather-dock-content .custom-content[data-v-4407d75f] {
.feather-dock > .feather-dock-content .custom-content[data-v-cd4a218e] {
text-align: center;
padding: 1rem;
}
.feather-dock.dock-open > .feather-dock-resizer[data-v-cd4a218e] {
position: absolute;
top: 0;
bottom: 0;
/* Make the resizer easier to grab */
width: var(--feather-dock-resizer-width);
cursor: ew-resize;
z-index: var(--feather-zindex-fixed);
left: calc(var(--feather-dock-width));
right: auto;
border-width: 2px;
background-color: transparent;
}
.feather-dock.dock-open > .feather-dock-resizer .feather-dock-resizer-handle[data-v-cd4a218e] {
position: absolute;
top: 0;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: var(--feather-dock-resizer-width);
border-radius: 0.125rem;
background-color: transparent;
border-left: 2px solid transparent;
transition: background-color 0.25s ease-in-out 0.25s, border-left-color 0.25s ease-in-out 0.25s;
}
.feather-dock.dock-open > .feather-dock-resizer .feather-dock-resizer-handle[data-v-cd4a218e]:hover {
background-color: var(--feather-dock-background-color);
border-left: 2px solid var(--feather-dock-color);
border-right: none;
}
.feather-dock.dock-open.right > .feather-dock-resizer[data-v-cd4a218e] {
position: absolute;
top: 0;
bottom: 0;
/* Make the resizer easier to grab */
width: var(--feather-dock-resizer-width);
cursor: ew-resize;
z-index: var(--feather-zindex-fixed);
left: auto;
right: calc(var(--feather-dock-width));
background-color: transparent;
border-width: 2px;
background-color: transparent;
}
.feather-dock.dock-open.right > .feather-dock-resizer .feather-dock-resizer-handle[data-v-cd4a218e] {
position: absolute;
top: 0;
bottom: 0;
right: 50%;
width: var(--feather-dock-resizer-width);
border-radius: 0.125rem;
background-color: transparent;
border-right: 2px solid transparent;
transition: background-color 0.25s ease-in-out 0.25s, border-right-color 0.25s ease-in-out 0.25s;
}
.feather-dock.dock-open.right > .feather-dock-resizer .feather-dock-resizer-handle[data-v-cd4a218e]:hover {
background-color: var(--feather-dock-background-color);
border-right: 2px solid var(--feather-dock-color);
border-left: none;
}
.feather-dock.is-resizing[data-v-cd4a218e] {
transition-duration: 0s;
}
.feather-dock.is-resizing > .feather-dock-toggle[data-v-cd4a218e] {
transition-duration: 0s;
}
{
"name": "@featherds/dock",
"version": "0.12.42",
"version": "0.12.43",
"publishConfig": {

@@ -12,4 +12,4 @@ "access": "public"

"dependencies": {
"@featherds/icon": "^0.12.42",
"@featherds/styles": "^0.12.42",
"@featherds/icon": "^0.12.43",
"@featherds/styles": "^0.12.43",
"vue": "^3.5.13"

@@ -22,3 +22,3 @@ },

"types": "./src/index.d.ts",
"gitHead": "e807ef35c30f4d9ef4a08ac173dfd50e3f2004d7"
"gitHead": "749671ccc8294eaf77881b9fea0e42980646e70a"
}

@@ -42,2 +42,8 @@ <template>

</div>
<div class="feather-dock-resizer">
<div
class="feather-dock-resizer-handle"
@pointerdown="onResizerDown"
></div>
</div>
</component>

@@ -80,2 +86,3 @@ </template>

"update:dock-collapsed",
"update:dock-resized",
]);

@@ -97,2 +104,3 @@

"dock-closed": !isDockOpen.value,
"is-resizing": isResizing.value,
[props.location]: true,

@@ -106,8 +114,104 @@ };

isOpen: isDockOpen.value,
isResizing: isResizing.value,
}));
const convertToPixels = (value: string): string => {
if (!value) return "0";
if (typeof value === "number") return value;
if (value.endsWith("px")) return parseInt(value, 10).toString();
const el = document.createElement("div");
el.style.position = "absolute";
el.style.visibility = "hidden";
el.style.width = value;
document.body.appendChild(el);
const pixels = el.getBoundingClientRect().width;
document.body.removeChild(el);
return pixels.toString();
};
const expandedWidthPx = computed(() => {
return `${convertToPixels(props.expandedWidth)}px`;
});
const collapsedWidthPx = computed(() => {
return `${convertToPixels(props.collapsedWidth)}px`;
});
// computed px values of provided widths
// (expandedWidthPx and collapsedWidthPx are declared above)
// currentExpandedWidth stores the current expanded width (in CSS units, usually px)
// and is updated when the user drags the resizer. Initialized from the prop.
const currentExpandedWidth = ref<string>(expandedWidthPx.value);
// Expose dockWidth as a CSS-ready string. When closed, use collapsed prop; when open, use currentExpandedWidth.
const dockWidth = computed(() => {
return dockConfig.value.isOpen ? props.expandedWidth : props.collapsedWidth;
return dockConfig.value.isOpen
? currentExpandedWidth.value
: props.collapsedWidth;
});
// Resizing state
const isResizing = ref(false);
const startX = ref(0);
const startWidthPx = ref(0);
// Keep local width in sync if prop changes externally
watch(
() => props.expandedWidth,
() => {
currentExpandedWidth.value = expandedWidthPx.value;
}
);
// --- Resizer handlers -------------------------------------------------
const onResizerDown = (event: PointerEvent) => {
// Only respond to primary pointer
if ((event as PointerEvent).isPrimary === false) return;
event.preventDefault();
isResizing.value = true;
startX.value = (event as PointerEvent).clientX;
// parse start width from currentExpandedWidth (assume px or numeric)
startWidthPx.value = parseInt(currentExpandedWidth.value as string, 10) || 0;
// Add global listeners
window.addEventListener("pointermove", onResizerMove);
window.addEventListener("pointerup", onResizerUp);
};
const onResizerMove = (event: PointerEvent) => {
if (!isResizing.value) return;
const clientX = (event as PointerEvent).clientX;
const delta = clientX - startX.value;
let newWidth = startWidthPx.value;
if (props.location === "left") {
newWidth = startWidthPx.value + delta;
} else {
newWidth = startWidthPx.value - delta;
}
// enforce minimum width = collapsedWidthPx
const minWidth = parseInt(convertToPixels(props.collapsedWidth), 10) || 48;
const maxWidth = Math.max(200, window.innerWidth - 64);
newWidth = Math.max(minWidth, Math.min(maxWidth, newWidth));
currentExpandedWidth.value = `${Math.round(newWidth)}px`;
// Update pushed elements live
updatePushedElement();
};
const onResizerUp = () => {
if (!isResizing.value) return;
isResizing.value = false;
window.removeEventListener("pointermove", onResizerMove);
window.removeEventListener("pointerup", onResizerUp);
emit("update:dock-resized", currentExpandedWidth.value);
};
const toggleDock = () => {

@@ -141,27 +245,2 @@ isDockOpen.value = !isDockOpen.value;

const convertToPixels = (value: string): string => {
if (!value) return "0";
if (typeof value === "number") return value;
if (value.endsWith("px")) return parseInt(value, 10).toString();
const el = document.createElement("div");
el.style.position = "absolute";
el.style.visibility = "hidden";
el.style.width = value;
document.body.appendChild(el);
const pixels = el.getBoundingClientRect().width;
document.body.removeChild(el);
return pixels.toString();
};
const expandedWidthPx = computed(() => {
return `${convertToPixels(props.expandedWidth)}px`;
});
const collapsedWidthPx = computed(() => {
return `${convertToPixels(props.collapsedWidth)}px`;
});
const updatePushedElement = () => {

@@ -189,5 +268,6 @@ if (!props.pushedSelector) return;

// Use the live currentExpandedWidth when the dock is open so pushed elements follow resizes
const widthFromProps = dockConfig.value.isOpen
? `${
parseInt(convertToPixels(props.expandedWidth)) +
parseInt(convertToPixels(currentExpandedWidth.value)) +
parseInt(convertToPixels(pushedSelectorPadding.value))

@@ -316,2 +396,8 @@ }px`

onUnmounted(() => {
// Cleanup any global pointer listeners used during resizing
if (isResizing.value) {
window.removeEventListener("pointermove", onResizerMove);
window.removeEventListener("pointerup", onResizerUp);
isResizing.value = false;
}
document.removeEventListener("keydown", handleSidebarEscape);

@@ -393,2 +479,3 @@ if (props.pushedSelector) {

--feather-dock-header-offset: 0px;
--feather-dock-resizer-width: 0.5rem;

@@ -477,4 +564,2 @@ @media (prefers-reduced-motion: reduce) {

transition-timing-function: var(--feather-dock-toggle-timing-fn);
// outline: 0.125rem solid var(--feather-background);
// outline-offset: -0.125rem;
font-size: 1rem;

@@ -492,3 +577,3 @@ z-index: calc(var(--feather-zindex-modal) + 1);

flex-direction: column;
align-items: center;
align-items: flex-start;

@@ -500,3 +585,75 @@ .custom-content {

}
&.dock-open > .feather-dock-resizer {
position: absolute;
top: 0;
bottom: 0;
/* Make the resizer easier to grab */
width: var(--feather-dock-resizer-width);
cursor: ew-resize;
z-index: var(vars.$zindex-fixed);
left: calc(var(--feather-dock-width));
right: auto;
border-width: 2px;
background-color: transparent;
.feather-dock-resizer-handle {
position: absolute;
top: 0;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: var(--feather-dock-resizer-width);
border-radius: 0.125rem;
background-color: transparent;
border-left: 2px solid transparent;
transition: background-color 0.25s ease-in-out 0.25s,
border-left-color 0.25s ease-in-out 0.25s;
&:hover {
background-color: var(--feather-dock-background-color);
border-left: 2px solid var(--feather-dock-color);
border-right: none;
}
}
}
&.dock-open.right > .feather-dock-resizer {
position: absolute;
top: 0;
bottom: 0;
/* Make the resizer easier to grab */
width: var(--feather-dock-resizer-width);
cursor: ew-resize;
z-index: var(vars.$zindex-fixed);
left: auto;
right: calc(var(--feather-dock-width));
background-color: transparent;
border-width: 2px;
background-color: transparent;
.feather-dock-resizer-handle {
position: absolute;
top: 0;
bottom: 0;
right: 50%;
width: var(--feather-dock-resizer-width);
border-radius: 0.125rem;
background-color: transparent;
border-right: 2px solid transparent;
transition: background-color 0.25s ease-in-out 0.25s,
border-right-color 0.25s ease-in-out 0.25s;
&:hover {
background-color: var(--feather-dock-background-color);
border-right: 2px solid var(--feather-dock-color);
border-left: none;
}
}
}
&.is-resizing {
transition-duration: 0s;
> .feather-dock-toggle {
transition-duration: 0s;
}
}
}
</style>

@@ -7,2 +7,3 @@ export type DockLocation = "left" | "right" | "none";

isOpen: boolean;
isResizing?: boolean;
}

@@ -9,0 +10,0 @@