@ data- slot/ resizable (中文(简体) )
香草JavaScript的无头可调整面板组. 无障碍而无作相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相.
灵感来自 反应-可逆小板 这样shadcn/ui-tyle组件库就可以把它作为滴入的原始.
安装
npm install @data-slot/resizable
快速启动
<div data-slot="resizable" data-direction="horizontal">
<div data-slot="resizable-panel" data-default-size="50" data-min-size="20">Left</div>
<div data-slot="resizable-handle" aria-label="Resize panels"></div>
<div data-slot="resizable-panel" data-default-size="50">Right</div>
</div>
<script type="module">
import { create } from "@data-slot/resizable";
const controllers = create();
</script>
API 密码
初始化
create(scope?)
在一个范围内自动发现并约束所有可迁移的组(默认为 document) (中文(简体) ).
import { create } from "@data-slot/resizable";
const controllers = create(); // Returns ResizableController[]
createResizable(root, options?)
为特定元素创建控制器.
import { createResizable } from "@data-slot/resizable";
const resizable = createResizable(element, {
direction: "horizontal",
keyboardResizeBy: 10,
onLayoutChange: (layout) => console.log(layout),
});
槽数
| 槽 | 说明 |
|---|---|
resizable | 组的根弹性容器 |
resizable-panel | 具有百分比大小的面板 |
resizable-handle | 相邻面板之间的可焦点分隔符 |
<div data-slot="resizable">
<div data-slot="resizable-panel">A</div>
<div data-slot="resizable-handle" aria-label="Resize panels"></div>
<div data-slot="resizable-panel">B</div>
</div>
组至少需要一个 resizable-panel,准确的说是一个
resizable-handle 在相邻的相邻的相片之间.
数据属性
选项也可以通过数据属性设定. 联合来文的选择优先.
根上为:
| 属性 | 类型 | 默认 | 说明 |
|---|---|---|---|
data-direction | 字符串 | horizontal | 布局轴 |
data-keyboard-resize-by | 编号 | 10 | 每个箭头按键压移动百分比 |
每个 resizable-panel数字 :
| 属性 | 类型 | 默认 | 说明 |
|---|---|---|---|
data-default-size | 编号 | 甚至是分开 | 初始规模(%) |
data-min-size | 编号 | 0 | 最小规模(%) |
data-max-size | 编号 | 100 | 最大规模(%) |
data-collapsible | 布尔 | false | 窗帘会倒塌 |
data-collapsed-size | 编号 | 0 | 倒塌时的大小(%) |
小组的规模和限制必须在0至100之间. minSize 不得超过
maxSize和相撞面板的 collapsedSize 不得超过 minSize。 。 。 .
限制必须允许布局总计100%;如果是初始化,则投出
无法。 相撞面板可占据已倒塌的大小或相撞面板之间的任何大小
它的最小和最大.
选项
| 选项 | 类型 | 默认 | 说明 |
|---|---|---|---|
direction | "horizontal" | "vertical" | "horizontal" | 布局轴 |
keyboardResizeBy | number | 10 | 每个箭头按键压移动百分比 |
onLayoutChange | (layout: number[]) => void | undefined | 当布局改变时调用 |
主计长
平板指数从零开始. setLayout() 需要一个有限、非负数
每个面板和一个正总数; 它使值正常化为100%,并应用
面板限制。 不改变当前布局而丢出无效的布局 .
resizePane() 需要一定的尺寸。 指数突变方法和 getSize()
丢入无效的窗格索引.
| 方法/财产 | 说明 |
|---|---|
layout | 当前布局为 number[] 百分比(只读) |
setLayout(sizes) | 设置完整布局( 验证/ 声明) |
resizePane(index, size) | 将窗格大小调整为 size百分比(%) |
collapse(index) | 折叠可折叠的窗格 |
expand(index) | 扩展已倒塌的窗格 |
isCollapsed(index) | 窗帘是否崩溃 |
isExpanded(index) | 是否扩展窗格 |
getSize(index) | 当前窗格的大小(%) |
destroy() | 清理所有听众和全局样式 |
活动
境外事件
element.addEventListener("resizable:change", (e) => {
console.log("Layout:", e.detail.layout);
});
element.addEventListener("resizable:dragging", (e) => {
console.log("Dragging:", e.detail.dragging);
});
入境事件
| 活动 | 细节 | 说明 |
|---|---|---|
resizable:set | { layout: number[] } | 按程序设置布局 |
element.dispatchEvent(new CustomEvent("resizable:set", { detail: { layout: [30, 70] } }));
样式
构成部分 flex 样式直接放在根和面板上。 给小组
高度和手柄为可见宽度或高度。 使用 data-* 属性
视觉造型 :
/* Style the handle */
[data-slot="resizable-handle"] {
width: 4px;
background: #ccc;
}
[data-slot="resizable"][data-direction="vertical"] [data-slot="resizable-handle"] {
width: 100%;
height: 4px;
}
/* Active drag / keyboard focus */
[data-slot="resizable-handle"][data-active] {
background: #2563eb;
}
/* Collapsed pane */
[data-slot="resizable-panel"][data-collapsed] {
opacity: 0;
}
于 flex-grow 用于动画崩溃/扩展:
[data-slot="resizable-panel"] {
transition: flex-grow 0.2s ease;
}
键盘导航
将手柄聚焦于 Tab 使用这些密钥之前 :
| 密钥 | 行动 |
|---|---|
ArrowLeft 编号 : ArrowRight | 将水平组大小由 keyboardResizeBy (默认为10%) |
ArrowUp 编号 : ArrowDown | 在同一步骤下调整垂直组大小 |
Shift + 箭头键 | 移动到这个方向的极限 |
Home 编号 : End | 在限制范围内尽量减少/尽量扩大前一个小组 |
Enter | 当上一个面板相撞时切换崩溃 |
F6 编号 : Shift + 键 F6 | 聚焦下一个/ 上一个手柄, 在组内包装 |
无障碍
该组件自动处理 :
role="separator"每个手柄上aria-orientation(与布局方向相接)aria-controls将每个手柄与上一个相连接aria-valuemin编号 :aria-valuemax编号 :aria-valuenow反映生活制约因素- 唯一用于根、窗体和手柄的ID生成
给每个手柄一个可用的名称 aria-label 或者说 aria-labelledby。 。 。 .
行为
切换输入方法
键盘调整大小和有效必要的布局更新结束 应用更改。 后续指针移动在新拖曳之前没有效果 启动。 每个文档中每次只能拖放一组.
所有输入方法都记得一个面板在倒塌前的大小.
expand() 财务报告和审定财务报表 Enter 恢复这个尺寸,但受其他小组的限制.
一个最初被倒塌的面板在没有先前大小的情况下会扩展到最小大小.
持续布局
没有内在的持久性,但阅读和恢复分裂是一个 单线 :
import { createResizable } from "@data-slot/resizable";
const el = document.querySelector('[data-slot="resizable"]');
const saved = localStorage.getItem("layout:sidebar");
const resizable = createResizable(el, {
onLayoutChange(layout) {
localStorage.setItem("layout:sidebar", JSON.stringify(layout));
},
});
if (saved) resizable.setLayout(JSON.parse(saved));
许可证
麻省理工学院