@iris-ui-kit/vue 0.1.0 → 0.2.1
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/admin.cjs +385 -25
- package/dist/admin.cjs.map +1 -1
- package/dist/admin.d.cts +108 -5
- package/dist/admin.d.ts +108 -5
- package/dist/admin.js +2 -1
- package/dist/behaviors.cjs +5 -1
- package/dist/behaviors.cjs.map +1 -1
- package/dist/behaviors.d.cts +10 -1
- package/dist/behaviors.d.ts +10 -1
- package/dist/behaviors.js +2 -1
- package/dist/{chunk-FJBYAIL4.js → chunk-4V4CT3Z4.js} +213 -31
- package/dist/chunk-4V4CT3Z4.js.map +1 -0
- package/dist/{chunk-CIZGSGXN.js → chunk-CWXH44OF.js} +4 -162
- package/dist/chunk-CWXH44OF.js.map +1 -0
- package/dist/chunk-W3B6E5GN.js +170 -0
- package/dist/chunk-W3B6E5GN.js.map +1 -0
- package/dist/index.cjs +702 -437
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +174 -77
- package/dist/index.d.ts +174 -77
- package/dist/index.js +205 -143
- package/dist/index.js.map +1 -1
- package/package.json +96 -11
- package/dist/chunk-CIZGSGXN.js.map +0 -1
- package/dist/chunk-FJBYAIL4.js.map +0 -1
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { defineComponent, ref, onBeforeUnmount, h } from 'vue';
|
|
2
|
+
import { createSortable } from '@iris-ui-kit/core';
|
|
3
|
+
|
|
4
|
+
// src/behaviors/Sortable.ts
|
|
5
|
+
var SORTABLE_ITEM_ATTR = "data-iris-sortable-item";
|
|
6
|
+
var IrisSortable = defineComponent({
|
|
7
|
+
name: "IrisSortable",
|
|
8
|
+
inheritAttrs: false,
|
|
9
|
+
props: {
|
|
10
|
+
/** The ordered items. Used to detect which item is at which position. */
|
|
11
|
+
items: {
|
|
12
|
+
type: Array,
|
|
13
|
+
required: true
|
|
14
|
+
},
|
|
15
|
+
/** Called when the user drops an item in a new position. */
|
|
16
|
+
onReorder: {
|
|
17
|
+
type: Function,
|
|
18
|
+
default: void 0
|
|
19
|
+
},
|
|
20
|
+
/** Optional item key getter. Defaults to `String(index)`. */
|
|
21
|
+
getKey: {
|
|
22
|
+
type: Function,
|
|
23
|
+
default: void 0
|
|
24
|
+
},
|
|
25
|
+
disabled: {
|
|
26
|
+
type: Boolean,
|
|
27
|
+
default: false
|
|
28
|
+
},
|
|
29
|
+
orientation: {
|
|
30
|
+
type: String,
|
|
31
|
+
default: "vertical"
|
|
32
|
+
},
|
|
33
|
+
class: {
|
|
34
|
+
type: String,
|
|
35
|
+
default: void 0
|
|
36
|
+
},
|
|
37
|
+
style: {
|
|
38
|
+
type: Object,
|
|
39
|
+
default: void 0
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
emits: {
|
|
43
|
+
reorder: (_next) => true
|
|
44
|
+
},
|
|
45
|
+
setup(props, { slots, attrs, emit }) {
|
|
46
|
+
const containerRef = ref(null);
|
|
47
|
+
const sortable = createSortable();
|
|
48
|
+
const activeKey = ref(null);
|
|
49
|
+
const unsub = sortable.subscribe((state) => {
|
|
50
|
+
activeKey.value = state.activeId;
|
|
51
|
+
});
|
|
52
|
+
onBeforeUnmount(unsub);
|
|
53
|
+
const indexOf = (key) => {
|
|
54
|
+
const container = containerRef.value;
|
|
55
|
+
if (!container) return -1;
|
|
56
|
+
return Array.from(
|
|
57
|
+
container.querySelectorAll(`[${SORTABLE_ITEM_ATTR}]`)
|
|
58
|
+
).findIndex((el) => el.getAttribute(SORTABLE_ITEM_ATTR) === key);
|
|
59
|
+
};
|
|
60
|
+
const onPointerDown = (e) => {
|
|
61
|
+
if (props.disabled) return;
|
|
62
|
+
const target = e.target.closest(`[${SORTABLE_ITEM_ATTR}]`);
|
|
63
|
+
if (!target) return;
|
|
64
|
+
const container = containerRef.value;
|
|
65
|
+
if (!container) return;
|
|
66
|
+
const key = target.getAttribute(SORTABLE_ITEM_ATTR) ?? "";
|
|
67
|
+
const index = indexOf(key);
|
|
68
|
+
if (index < 0) return;
|
|
69
|
+
sortable.press(key, e.clientX, e.clientY);
|
|
70
|
+
};
|
|
71
|
+
const onPointerMove = (e) => {
|
|
72
|
+
if (!sortable.isPending() && sortable.getState().activeId === null) return;
|
|
73
|
+
const items = containerRef.value?.querySelectorAll(`[${SORTABLE_ITEM_ATTR}]`);
|
|
74
|
+
const rects = Array.from(items ?? []).map((el) => {
|
|
75
|
+
const rect = el.getBoundingClientRect();
|
|
76
|
+
return {
|
|
77
|
+
id: el.getAttribute(SORTABLE_ITEM_ATTR) ?? "",
|
|
78
|
+
left: rect.left,
|
|
79
|
+
top: rect.top,
|
|
80
|
+
width: rect.width,
|
|
81
|
+
height: rect.height
|
|
82
|
+
};
|
|
83
|
+
});
|
|
84
|
+
sortable.tryStart(e.clientX, e.clientY);
|
|
85
|
+
if (sortable.getState().activeId !== null) {
|
|
86
|
+
sortable.moveOver({ x: e.clientX, y: e.clientY }, rects);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
const onPointerUp = () => {
|
|
90
|
+
const state = sortable.getState();
|
|
91
|
+
if (state.activeId === null) {
|
|
92
|
+
sortable.cancel();
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
const result = sortable.end();
|
|
96
|
+
if (result.activeId && result.overId && result.activeId !== result.overId) {
|
|
97
|
+
const from = indexOf(result.activeId);
|
|
98
|
+
const to = indexOf(result.overId);
|
|
99
|
+
if (from >= 0 && to >= 0) {
|
|
100
|
+
const next = [...props.items];
|
|
101
|
+
const [moved] = next.splice(from, 1);
|
|
102
|
+
next.splice(to, 0, moved);
|
|
103
|
+
if (props.onReorder) {
|
|
104
|
+
props.onReorder(next);
|
|
105
|
+
}
|
|
106
|
+
emit("reorder", next);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
const resolveKey = (item, index) => props.getKey ? props.getKey(item, index) : String(index);
|
|
111
|
+
return () => {
|
|
112
|
+
const children = [];
|
|
113
|
+
const defaultSlots = slots.default?.();
|
|
114
|
+
if (defaultSlots) {
|
|
115
|
+
const itemsArray = props.items;
|
|
116
|
+
defaultSlots.forEach((child, index) => {
|
|
117
|
+
const item = itemsArray[index];
|
|
118
|
+
const key = resolveKey(item, index);
|
|
119
|
+
const isDragging = key === activeKey.value;
|
|
120
|
+
children.push(
|
|
121
|
+
h(
|
|
122
|
+
"div",
|
|
123
|
+
{
|
|
124
|
+
key,
|
|
125
|
+
[SORTABLE_ITEM_ATTR]: key,
|
|
126
|
+
"data-iris-sortable-dragging": isDragging ? "" : void 0,
|
|
127
|
+
style: {
|
|
128
|
+
transition: isDragging ? "none" : "transform 150ms ease",
|
|
129
|
+
opacity: isDragging ? 0.4 : 1,
|
|
130
|
+
position: "relative",
|
|
131
|
+
zIndex: isDragging ? 100 : void 0
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
[child]
|
|
135
|
+
)
|
|
136
|
+
);
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
return h(
|
|
140
|
+
"div",
|
|
141
|
+
{
|
|
142
|
+
...attrs,
|
|
143
|
+
ref: (el) => {
|
|
144
|
+
containerRef.value = el ?? null;
|
|
145
|
+
},
|
|
146
|
+
"data-iris-sortable": "",
|
|
147
|
+
"data-state": activeKey.value ? "dragging" : "idle",
|
|
148
|
+
class: props.class,
|
|
149
|
+
style: {
|
|
150
|
+
display: "flex",
|
|
151
|
+
flexDirection: props.orientation === "horizontal" ? "row" : "column",
|
|
152
|
+
gap: "var(--iris-gap-sm, 4px)",
|
|
153
|
+
opacity: props.disabled ? 0.6 : 1,
|
|
154
|
+
userSelect: activeKey.value ? "none" : void 0,
|
|
155
|
+
...props.style ?? {}
|
|
156
|
+
},
|
|
157
|
+
onPointerdown: onPointerDown,
|
|
158
|
+
onPointermove: onPointerMove,
|
|
159
|
+
onPointerup: onPointerUp,
|
|
160
|
+
onPointerleave: onPointerUp
|
|
161
|
+
},
|
|
162
|
+
children
|
|
163
|
+
);
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
export { IrisSortable, SORTABLE_ITEM_ATTR };
|
|
169
|
+
//# sourceMappingURL=chunk-W3B6E5GN.js.map
|
|
170
|
+
//# sourceMappingURL=chunk-W3B6E5GN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/behaviors/Sortable.ts"],"names":[],"mappings":"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","file":"chunk-W3B6E5GN.js","sourcesContent":["import { defineComponent, h, onBeforeUnmount, ref, type PropType, type VNode } from 'vue'\nimport { createSortable, type SortableRect } from '@iris-ui-kit/core'\n\n/** The data attribute on each sortable item for the collision system. */\nexport const SORTABLE_ITEM_ATTR = 'data-iris-sortable-item'\n\n/**\n * Behavior wrapper: makes a list of items sortable via drag-and-drop. Wraps\n * each direct child in a sortable item context. The consumer supplies the\n * `items` array and an `onReorder` callback. Items render through the default\n * slot; each item is wrapped with drag detection from `createSortable`.\n *\n * Composable: stack with `IrisResizable` / `IrisMovable` / `IrisHotkey` for\n * richer interactions on the same wrapped UI.\n *\n * @example\n * <IrisSortable :items=\"items\" @reorder=\"items = $event\">\n * <div v-for=\"(label, i) in items\" :key=\"i\">{{ label }}</div>\n * </IrisSortable>\n */\nexport const IrisSortable = defineComponent({\n name: 'IrisSortable',\n inheritAttrs: false,\n props: {\n /** The ordered items. Used to detect which item is at which position. */\n items: {\n type: Array as PropType<readonly unknown[]>,\n required: true,\n },\n /** Called when the user drops an item in a new position. */\n onReorder: {\n type: Function as PropType<(next: unknown[]) => void>,\n default: undefined,\n },\n /** Optional item key getter. Defaults to `String(index)`. */\n getKey: {\n type: Function as PropType<(item: unknown, index: number) => string>,\n default: undefined,\n },\n disabled: {\n type: Boolean,\n default: false,\n },\n orientation: {\n type: String as PropType<'vertical' | 'horizontal'>,\n default: 'vertical',\n },\n class: {\n type: String,\n default: undefined,\n },\n style: {\n type: Object as PropType<Record<string, string | number>>,\n default: undefined,\n },\n },\n emits: {\n reorder: (_next: unknown[]) => true,\n },\n setup(props, { slots, attrs, emit }) {\n const containerRef = ref<HTMLElement | null>(null)\n const sortable = createSortable()\n const activeKey = ref<string | null>(null)\n\n // Subscribe to sortable state changes to track the active drag key\n const unsub = sortable.subscribe((state) => {\n activeKey.value = state.activeId\n })\n onBeforeUnmount(unsub)\n\n // Find the DOM order index of a child by its data-iris-sortable-item value.\n const indexOf = (key: string): number => {\n const container = containerRef.value\n if (!container) return -1\n return Array.from(\n container.querySelectorAll<HTMLElement>(`[${SORTABLE_ITEM_ATTR}]`),\n ).findIndex((el) => el.getAttribute(SORTABLE_ITEM_ATTR) === key)\n }\n\n const onPointerDown = (e: PointerEvent) => {\n if (props.disabled) return\n const target = (e.target as HTMLElement).closest(`[${SORTABLE_ITEM_ATTR}]`)\n if (!target) return\n const container = containerRef.value\n if (!container) return\n const key = target.getAttribute(SORTABLE_ITEM_ATTR) ?? ''\n const index = indexOf(key)\n if (index < 0) return\n sortable.press(key, e.clientX, e.clientY)\n }\n\n const onPointerMove = (e: PointerEvent) => {\n if (!sortable.isPending() && sortable.getState().activeId === null) return\n const items = containerRef.value?.querySelectorAll<HTMLElement>(`[${SORTABLE_ITEM_ATTR}]`)\n const rects: SortableRect[] = Array.from(items ?? []).map((el) => {\n const rect = el.getBoundingClientRect()\n return {\n id: el.getAttribute(SORTABLE_ITEM_ATTR) ?? '',\n left: rect.left,\n top: rect.top,\n width: rect.width,\n height: rect.height,\n }\n })\n // Promote pending press to active drag once past the movement threshold\n sortable.tryStart(e.clientX, e.clientY)\n if (sortable.getState().activeId !== null) {\n sortable.moveOver({ x: e.clientX, y: e.clientY }, rects)\n }\n }\n\n const onPointerUp = () => {\n const state = sortable.getState()\n if (state.activeId === null) {\n sortable.cancel()\n return\n }\n const result = sortable.end()\n if (result.activeId && result.overId && result.activeId !== result.overId) {\n const from = indexOf(result.activeId)\n const to = indexOf(result.overId)\n if (from >= 0 && to >= 0) {\n const next = [...(props.items as unknown[])]\n const [moved] = next.splice(from, 1)\n next.splice(to, 0, moved!)\n if (props.onReorder) {\n props.onReorder(next)\n }\n emit('reorder', next)\n }\n }\n }\n\n const resolveKey = (item: unknown, index: number): string =>\n props.getKey ? props.getKey(item, index) : String(index)\n\n return () => {\n const children: VNode[] = []\n const defaultSlots = slots.default?.()\n if (defaultSlots) {\n const itemsArray = props.items as unknown[]\n defaultSlots.forEach((child, index) => {\n const item = itemsArray[index]\n const key = resolveKey(item, index)\n const isDragging = key === activeKey.value\n children.push(\n h(\n 'div',\n {\n key,\n [SORTABLE_ITEM_ATTR]: key,\n 'data-iris-sortable-dragging': isDragging ? '' : undefined,\n style: {\n transition: isDragging ? 'none' : 'transform 150ms ease',\n opacity: isDragging ? 0.4 : 1,\n position: 'relative',\n zIndex: isDragging ? 100 : undefined,\n },\n },\n [child],\n ),\n )\n })\n }\n\n return h(\n 'div',\n {\n ...attrs,\n ref: (el: unknown) => {\n containerRef.value = (el ?? null) as HTMLElement | null\n },\n 'data-iris-sortable': '',\n 'data-state': activeKey.value ? 'dragging' : 'idle',\n class: props.class,\n style: {\n display: 'flex',\n flexDirection: props.orientation === 'horizontal' ? 'row' : 'column',\n gap: 'var(--iris-gap-sm, 4px)',\n opacity: props.disabled ? 0.6 : 1,\n userSelect: activeKey.value ? 'none' : undefined,\n ...((props.style as Record<string, string | number> | undefined) ?? {}),\n },\n onPointerdown: onPointerDown,\n onPointermove: onPointerMove,\n onPointerup: onPointerUp,\n onPointerleave: onPointerUp,\n },\n children,\n )\n }\n },\n})\n"]}
|