@startupjs-ui/draggable 0.1.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/CHANGELOG.md ADDED
@@ -0,0 +1,20 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
+
6
+ ## [0.1.3](https://github.com/startupjs/startupjs-ui/compare/v0.1.2...v0.1.3) (2025-12-29)
7
+
8
+ **Note:** Version bump only for package @startupjs-ui/draggable
9
+
10
+
11
+
12
+
13
+
14
+ ## [0.1.2](https://github.com/startupjs/startupjs-ui/compare/v0.1.1...v0.1.2) (2025-12-29)
15
+
16
+
17
+ ### Features
18
+
19
+ * add mdx and docs packages. Refactor docs to get rid of any @startupjs/ui usage and use startupjs-ui instead ([703c926](https://github.com/startupjs/startupjs-ui/commit/703c92636efb0421ffd11783f692fc892b74018f))
20
+ * **draggable:** refactor Draggable, Droppable, DragDropProvider components ([edf54e1](https://github.com/startupjs/startupjs-ui/commit/edf54e1171f6e89737281d580567b559d585d242))
@@ -0,0 +1,28 @@
1
+ import React, { type ReactNode } from 'react'
2
+ import { pug, $ } from 'startupjs'
3
+
4
+ export const DragDropContext = React.createContext<any>({})
5
+
6
+ export const _PropsJsonSchema = {/* DragDropProviderProps */}
7
+
8
+ export interface DragDropProviderProps {
9
+ /** Components rendered inside provider */
10
+ children?: ReactNode
11
+ }
12
+
13
+ export default function DragDropProvider ({
14
+ children
15
+ }: DragDropProviderProps): ReactNode {
16
+ const $context = $({
17
+ dropHoverId: '',
18
+ dragHoverIndex: null,
19
+ activeData: {},
20
+ drops: {},
21
+ drags: {}
22
+ })
23
+
24
+ return pug`
25
+ DragDropContext.Provider(value=$context)
26
+ = children
27
+ `
28
+ }
@@ -0,0 +1,252 @@
1
+ import React, { useContext, useEffect, useRef, type ReactNode } from 'react'
2
+ import { Animated, View, StyleSheet, type StyleProp, type ViewStyle } from 'react-native'
3
+ import { State, PanGestureHandler } from 'react-native-gesture-handler'
4
+ import { pug, observer } from 'startupjs'
5
+ import { themed } from '@startupjs-ui/core'
6
+ import Portal from '@startupjs-ui/portal'
7
+ import { DragDropContext } from '../DragDropProvider'
8
+ import '../index.cssx.styl'
9
+
10
+ export const _PropsJsonSchema = {/* DraggableProps */}
11
+
12
+ export interface DraggableProps {
13
+ /** Content rendered inside draggable item */
14
+ children?: ReactNode
15
+ /** Custom styles applied to the draggable item */
16
+ style?: StyleProp<ViewStyle>
17
+ /** Drag type (useful for filtering drop targets) */
18
+ type?: string
19
+ /** Unique draggable item id */
20
+ dragId: string
21
+ /** @private Drop id injected by Droppable */
22
+ _dropId?: string
23
+ /** @private Index injected by Droppable */
24
+ _index?: number
25
+ /** Called when drag begins */
26
+ onDragBegin?: (options: {
27
+ dragId: string
28
+ dropId: string
29
+ dropHoverId: string
30
+ hoverIndex: number
31
+ }) => void
32
+ /** Called when drag ends */
33
+ onDragEnd?: (options: {
34
+ dragId: string
35
+ dropId: string
36
+ dropHoverId: string
37
+ hoverIndex: number
38
+ }) => void
39
+ }
40
+
41
+ function Draggable ({
42
+ children,
43
+ style,
44
+ type,
45
+ dragId,
46
+ _dropId,
47
+ _index,
48
+ onDragBegin,
49
+ onDragEnd
50
+ }: DraggableProps): ReactNode {
51
+ const ref = useRef<any>(null)
52
+ const $dndContext = useContext(DragDropContext)
53
+
54
+ const animateStates = {
55
+ left: new Animated.Value(0),
56
+ top: new Animated.Value(0)
57
+ }
58
+
59
+ // init drags.dragId
60
+ useEffect(() => {
61
+ $dndContext.drags[dragId].set({ ref, style: {} })
62
+ }, [ // eslint-disable-line react-hooks/exhaustive-deps
63
+ dragId,
64
+ _dropId,
65
+ _index,
66
+ $dndContext.drags[dragId].ref.current.get() // eslint-disable-line react-hooks/exhaustive-deps
67
+ ])
68
+
69
+ if (_dropId == null || _index == null) {
70
+ return pug`
71
+ View(style=style)= children
72
+ `
73
+ }
74
+
75
+ const dropId = _dropId
76
+ const index = _index
77
+
78
+ function onHandlerStateChange ({ nativeEvent }: any) {
79
+ const data = {
80
+ type,
81
+ dragId,
82
+ dropId,
83
+ dragStyle: { ...StyleSheet.flatten(style) },
84
+ startPosition: {
85
+ x: nativeEvent.x,
86
+ y: nativeEvent.y
87
+ }
88
+ }
89
+
90
+ if (nativeEvent.state === State.BEGAN) {
91
+ ref.current.measure((dragX: any, dragY: any, dragWidth: any, dragHeight: any) => {
92
+ data.dragStyle.height = dragHeight
93
+
94
+ $dndContext.drops[dropId].ref.current.get().measure((dx: any, dy: any, dw: any, dropHeight: any) => {
95
+ // init states
96
+ $dndContext.drags[dragId].style.set({ display: 'none' })
97
+ $dndContext.assign({
98
+ activeData: data,
99
+ dropHoverId: dropId,
100
+ dragHoverIndex: index
101
+ })
102
+
103
+ onDragBegin && onDragBegin({
104
+ dragId: data.dragId,
105
+ dropId: data.dropId,
106
+ dropHoverId: dropId,
107
+ hoverIndex: index
108
+ })
109
+ })
110
+ })
111
+ }
112
+
113
+ if (nativeEvent.state === State.END) {
114
+ animateStates.left.setValue(0)
115
+ animateStates.top.setValue(0)
116
+
117
+ onDragEnd && onDragEnd({
118
+ dragId: $dndContext.activeData.dragId.get(),
119
+ dropId: $dndContext.activeData.dropId.get(),
120
+ dropHoverId: $dndContext.dropHoverId.get(),
121
+ hoverIndex: $dndContext.dragHoverIndex.get()
122
+ })
123
+
124
+ // reset states
125
+ $dndContext.assign({
126
+ drags: {
127
+ [dragId]: { style: {} }
128
+ },
129
+ activeData: {},
130
+ dropHoverId: '',
131
+ dragHoverIndex: null
132
+ })
133
+ }
134
+ }
135
+
136
+ function onGestureEvent ({ nativeEvent }: any) {
137
+ if (!$dndContext.dropHoverId.get()) return
138
+
139
+ animateStates.left.setValue(
140
+ nativeEvent.absoluteX - $dndContext.activeData.startPosition.x.get()
141
+ )
142
+ animateStates.top.setValue(
143
+ nativeEvent.absoluteY - $dndContext.activeData.startPosition.y.get()
144
+ )
145
+
146
+ $dndContext.activeData.x.set(nativeEvent.absoluteX)
147
+ $dndContext.activeData.y.set(nativeEvent.absoluteY)
148
+ checkPosition($dndContext.activeData.get())
149
+ }
150
+
151
+ function checkPosition (activeData: any) {
152
+ $dndContext.drops[dropId].ref.current.get().measure(async (dX: any, dY: any, dWidth: any, dHeight: any, dPageX: any, dPageY: any) => {
153
+ const positions: any[] = []
154
+ let startPosition = dPageY
155
+ let endPosition = dPageY
156
+
157
+ const dragsLength = $dndContext.drops[$dndContext.dropHoverId.get()].items.get()?.length || 0
158
+
159
+ for (let index = 0; index < dragsLength; index++) {
160
+ if (!$dndContext.dropHoverId.get()) break
161
+
162
+ const iterDragId = $dndContext.drops[$dndContext.dropHoverId.get()].items[index].get()
163
+
164
+ await new Promise<void>(resolve => {
165
+ const currentElement = $dndContext.drags[iterDragId].ref.current.get()
166
+ if (!currentElement) {
167
+ positions.push(null)
168
+ resolve()
169
+ return
170
+ }
171
+ currentElement.measure((x: any, y: any, width: any, height: any, pageX: any, pageY: any) => {
172
+ if (index === 0) {
173
+ startPosition = dPageY
174
+ endPosition = dPageY + y + (height / 2)
175
+ } else {
176
+ startPosition = endPosition
177
+ endPosition = pageY + (height / 2)
178
+ }
179
+
180
+ if (iterDragId === dragId) {
181
+ positions.push(null)
182
+ } else {
183
+ positions.push({ start: startPosition, end: endPosition })
184
+ }
185
+
186
+ resolve()
187
+ })
188
+ })
189
+ }
190
+
191
+ positions.push({ start: endPosition, end: dPageY + dHeight })
192
+
193
+ for (let index = 0; index < positions.length; index++) {
194
+ const position = positions[index]
195
+ if (!position) continue
196
+
197
+ if (activeData.y > position.start && activeData.y < position.end) {
198
+ $dndContext.dragHoverIndex.set(index)
199
+ break
200
+ }
201
+ }
202
+ })
203
+ }
204
+
205
+ const contextStyle = $dndContext.drags[dragId].style.get() || {}
206
+ const _style: any = StyleSheet.flatten([style, animateStates])
207
+
208
+ const isShowPlaceholder = $dndContext.activeData.get() &&
209
+ $dndContext.dropHoverId.get() === dropId &&
210
+ $dndContext.dragHoverIndex.get() === index
211
+
212
+ const isShowLastPlaceholder = $dndContext.activeData.get() &&
213
+ $dndContext.dropHoverId.get() === dropId &&
214
+ $dndContext.drops[dropId].items.get().length - 1 === index &&
215
+ $dndContext.dragHoverIndex.get() === index + 1
216
+
217
+ const placeholder = pug`
218
+ View.placeholder(
219
+ style={
220
+ height: $dndContext.activeData.get() && $dndContext.activeData.dragStyle.get() && $dndContext.activeData.dragStyle.height.get(),
221
+ marginTop: $dndContext.activeData.get() && $dndContext.activeData.dragStyle.get() && $dndContext.activeData.dragStyle.marginTop.get(),
222
+ marginBottom: $dndContext.activeData.get() && $dndContext.activeData.dragStyle.get() && $dndContext.activeData.dragStyle.marginBottom.get()
223
+ }
224
+ )
225
+ `
226
+
227
+ return pug`
228
+ if isShowPlaceholder
229
+ = placeholder
230
+
231
+ Portal
232
+ if $dndContext.activeData.dragId.get() === dragId
233
+ Animated.View(style=[
234
+ _style,
235
+ { position: 'absolute', cursor: 'default' }
236
+ ])= children
237
+
238
+ PanGestureHandler(
239
+ onHandlerStateChange=onHandlerStateChange
240
+ onGestureEvent=onGestureEvent
241
+ )
242
+ Animated.View(
243
+ ref=ref
244
+ style=[style, contextStyle]
245
+ )= children
246
+
247
+ if isShowLastPlaceholder
248
+ = placeholder
249
+ `
250
+ }
251
+
252
+ export default observer(themed('Draggable', Draggable), { cache: false })
@@ -0,0 +1,98 @@
1
+ import React, { useRef, useEffect, useContext, type ReactNode } from 'react'
2
+ import { View, StatusBar, type StyleProp, type ViewStyle } from 'react-native'
3
+ import { pug, observer, $ } from 'startupjs'
4
+ import { themed } from '@startupjs-ui/core'
5
+ import { DragDropContext } from '../DragDropProvider'
6
+
7
+ export const _PropsJsonSchema = {/* DroppableProps */}
8
+
9
+ export interface DroppableProps {
10
+ /** Draggable items rendered inside the droppable area */
11
+ children?: ReactNode
12
+ /** Custom styles applied to the droppable container */
13
+ style?: StyleProp<ViewStyle>
14
+ /** Drop type (useful for filtering drags) */
15
+ type?: string
16
+ /** Unique droppable container id */
17
+ dropId: string
18
+ /** Called when active drag leaves this droppable */
19
+ onLeave?: () => void
20
+ /** Called when active drag enters this droppable */
21
+ onHover?: () => void
22
+ }
23
+
24
+ function Droppable ({
25
+ children,
26
+ style,
27
+ type,
28
+ dropId,
29
+ onLeave,
30
+ onHover
31
+ }: DroppableProps): ReactNode {
32
+ const ref = useRef<any>(null)
33
+ const $dndContext = useContext(DragDropContext)
34
+ const $isHover = $(false)
35
+
36
+ useEffect(() => {
37
+ $dndContext.drops[dropId].set({
38
+ ref,
39
+ items: React.Children.map(children as any, (child: any) => {
40
+ return child?.props?.dragId
41
+ })
42
+ })
43
+ }, [children, dropId, $dndContext])
44
+
45
+ useEffect(() => {
46
+ ref.current.measure((x: any, y: any, width: any, height: any, pageX: any, pageY: any) => {
47
+ if (!$dndContext.activeData.dragId.get() || !$dndContext.dropHoverId.get()) {
48
+ $isHover.set(false)
49
+ return
50
+ }
51
+
52
+ const leftBorder = pageX
53
+ const rightBorder = pageX + width
54
+ const topBorder = pageY
55
+ const bottomBorder = pageY + height
56
+
57
+ const isHoverUpdate = (
58
+ $dndContext.activeData.x.get() > leftBorder &&
59
+ $dndContext.activeData.x.get() < rightBorder &&
60
+ $dndContext.activeData.y.get() - (StatusBar.currentHeight ?? 0) > topBorder &&
61
+ $dndContext.activeData.y.get() - (StatusBar.currentHeight ?? 0) < bottomBorder
62
+ )
63
+
64
+ if (isHoverUpdate && !$isHover.get()) {
65
+ $dndContext.dropHoverId.set(dropId)
66
+ onHover && onHover() // TODO
67
+ }
68
+
69
+ if (!isHoverUpdate && $isHover.get()) {
70
+ onLeave && onLeave() // TODO
71
+ }
72
+
73
+ $isHover.set(isHoverUpdate)
74
+ })
75
+ // eslint-disable-next-line react-hooks/exhaustive-deps
76
+ }, [JSON.stringify($dndContext.activeData.get())])
77
+
78
+ const modChildren = React.Children.toArray(children).map((child: any, index) => {
79
+ return React.cloneElement(child, {
80
+ ...child.props,
81
+ _dropId: dropId,
82
+ _index: index
83
+ })
84
+ })
85
+
86
+ const hasActiveDrag = $dndContext.drops[dropId].items.get()?.includes($dndContext.activeData.dragId.get())
87
+ const activeStyle = hasActiveDrag ? { zIndex: 9999 } : {}
88
+ const contextStyle = $dndContext.drops[dropId].style.get() || {}
89
+
90
+ return pug`
91
+ View(
92
+ ref=ref
93
+ style=[style, activeStyle, contextStyle]
94
+ )= modChildren
95
+ `
96
+ }
97
+
98
+ export default observer(themed('Droppable', Droppable))
@@ -0,0 +1,39 @@
1
+ import React from 'react'
2
+ import { pug } from 'startupjs'
3
+ import Span from '@startupjs-ui/span'
4
+ import { Draggable, DragDropProvider, Droppable } from './index'
5
+
6
+ export function DragDropProviderSandbox ({ children, ...props }) {
7
+ return pug`
8
+ DragDropProvider(...props)
9
+ if children
10
+ = children
11
+ else
12
+ Droppable.droppable(dropId='sandbox-drop')
13
+ Draggable.draggable(dragId='sandbox-drag')
14
+ Span Drag me
15
+ `
16
+ }
17
+
18
+ export function DroppableSandbox (props) {
19
+ return pug`
20
+ DragDropProvider
21
+ Droppable.droppable(...props)
22
+ Draggable.draggable(dragId='a')
23
+ Span Item A
24
+ Draggable.draggable(dragId='b')
25
+ Span Item B
26
+ `
27
+ }
28
+
29
+ export function DraggableSandbox ({ children, ...props }) {
30
+ return pug`
31
+ DragDropProvider
32
+ Droppable.droppable(dropId='sandbox-drop')
33
+ Draggable.draggable(...props)
34
+ if children
35
+ = children
36
+ else
37
+ Span Drag me
38
+ `
39
+ }
package/README.mdx ADDED
@@ -0,0 +1,181 @@
1
+ import { useState } from 'react'
2
+ import { pug } from 'startupjs'
3
+ import { Sandbox } from '@startupjs-ui/docs'
4
+ import {
5
+ Draggable,
6
+ DragDropProvider,
7
+ Droppable,
8
+ _PropsJsonSchema as DraggablePropsJsonSchema
9
+ } from './index'
10
+ import { _PropsJsonSchema as DragDropProviderPropsJsonSchema } from './DragDropProvider'
11
+ import { _PropsJsonSchema as DroppablePropsJsonSchema } from './Droppable'
12
+ import Span from '@startupjs-ui/span'
13
+ import Div from '@startupjs-ui/div'
14
+ import ScrollView from '@startupjs-ui/scroll-view'
15
+ import {
16
+ DragDropProviderSandbox,
17
+ DroppableSandbox,
18
+ DraggableSandbox
19
+ } from './README.helpers'
20
+ import './index.mdx.cssx.styl'
21
+
22
+ # Draggable
23
+
24
+ `Draggable` provides simple building blocks for drag & drop on React Native / RN Web:
25
+
26
+ - `DragDropProvider` stores drag/drop state and exposes it via context
27
+ - `Droppable` marks a drop target and tracks the order of its children
28
+ - `Draggable` handles gestures and renders the dragged item into a `Portal`
29
+
30
+ ```jsx
31
+ import { DragDropProvider, Droppable, Draggable } from 'startupjs-ui'
32
+ ```
33
+
34
+ ## How it works
35
+
36
+ 1. Wrap the area with `DragDropProvider`.
37
+ 2. Inside it render one or more `Droppable`s with unique `dropId`.
38
+ 3. Render `Draggable`s inside each `Droppable`, each with a unique `dragId`.
39
+ 4. Update your own data in `onDragEnd` using `{ dragId, dropId, dropHoverId, hoverIndex }`.
40
+
41
+ ## Simple example (reorder in a single list)
42
+
43
+ ```jsx example
44
+ const [items, setItems] = useState([
45
+ { id: 'a', text: 'First' },
46
+ { id: 'b', text: 'Second' },
47
+ { id: 'c', text: 'Third' }
48
+ ])
49
+
50
+ function onDragEnd ({ dragId, dropId, dropHoverId, hoverIndex }) {
51
+ if (dropId !== dropHoverId) return
52
+ const fromIndex = items.findIndex(i => i.id === dragId)
53
+ if (fromIndex === -1) return
54
+
55
+ const next = [...items]
56
+ const [moved] = next.splice(fromIndex, 1)
57
+ const toIndex = hoverIndex > fromIndex ? hoverIndex - 1 : hoverIndex
58
+ next.splice(toIndex, 0, moved)
59
+ setItems(next)
60
+ }
61
+
62
+ return pug`
63
+ DragDropProvider
64
+ Droppable.droppable(dropId='list')
65
+ each item in items
66
+ Draggable.draggable(
67
+ key=item.id
68
+ dragId=item.id
69
+ onDragEnd=onDragEnd
70
+ )
71
+ Span= item.text
72
+ `
73
+ ```
74
+
75
+ ## Multi-column example (move items between columns)
76
+
77
+ This example implements a small kanban-like board:
78
+
79
+ - each column is a `Droppable`
80
+ - each card is a `Draggable`
81
+ - `onDragEnd` moves the dragged card to the hovered column and index
82
+
83
+ ```jsx example
84
+ const [data, setData] = useState([
85
+ {
86
+ id: '8c778cc6-c1dd-4dde-84a2-e3000fca8ffd',
87
+ title: 'Plan',
88
+ items: [
89
+ { id: '55bd3da0-bed0-451f-8ac3-3b9a19a699fb', text: 'Quarterly newsletter and other' },
90
+ { id: '8374e61f-0b95-4a4a-8282-48f9316f4157', text: 'Read a book' },
91
+ { id: '13febede-112d-4d53-8e6f-a83a184e229d', text: 'Buy a new gaming laptop' },
92
+ { id: '11aabadc-113d-4d53-8e6f-a83a184e229d', text: 'Buy a new gaming 2' },
93
+ { id: '12febadc-112d-4d53-8e6f-a83a184e229d', text: 'Buy a new gaming 3' }
94
+ ]
95
+ },
96
+ {
97
+ id: '2d503db0-c209-4f47-8b6a-96ef3ec6ade7',
98
+ title: 'WIP',
99
+ items: [
100
+ { id: '4174c327-eea0-4ec7-96fa-2dc319c40fd6', text: 'Interview John H.', style: {} },
101
+ { id: 'a2b3af0e-e482-468e-a681-3ab8303b208f', text: 'Sumbit updates to mobile storefronts', style: {} }
102
+ ]
103
+ },
104
+ {
105
+ id: 'be64729e-29d8-4399-88cd-f1ee3c48b0d8',
106
+ title: 'Complete',
107
+ items: [
108
+ { id: 'c539db23-77f3-49f8-93f0-2a10f1c1f1b7', text: 'Schedule meeting with Alex', style: {} },
109
+ { id: 'a0d82bf2-72f4-48ba-9294-b835862519ce', text: 'Homepage refresh', style: {} }
110
+ ]
111
+ }
112
+ ])
113
+
114
+ const arrInsertEl = (arr, index, item) => arr.splice(index, 0, item)
115
+ const arrRemoveEl = (arr, index) => arr.splice(index, 1)
116
+
117
+ function onDragEnd ({
118
+ dragId,
119
+ dropId,
120
+ dropHoverId,
121
+ hoverIndex
122
+ }) {
123
+ const dropIndex = data.findIndex(drop => drop.id === dropId)
124
+ const dropHoverIndex = data.findIndex(drop => drop.id === dropHoverId)
125
+ const dragIndex = data[dropIndex].items.findIndex(drag => drag.id === dragId)
126
+
127
+ const drag = data[dropIndex].items[dragIndex]
128
+
129
+ arrInsertEl(data[dropHoverIndex].items, hoverIndex, drag)
130
+ if (dropHoverId === dropId && hoverIndex < dragIndex) {
131
+ arrRemoveEl(data[dropIndex].items, dragIndex + 1)
132
+ } else {
133
+ arrRemoveEl(data[dropIndex].items, dragIndex)
134
+ }
135
+
136
+ setData([...data])
137
+ }
138
+
139
+ return pug`
140
+ DragDropProvider
141
+ ScrollView(horizontal=true)
142
+ Div(row)
143
+ each drop in data
144
+ Droppable.droppable(
145
+ key=drop.id
146
+ dropId=drop.id
147
+ )
148
+ each drag in drop.items
149
+ Draggable.draggable(
150
+ key=drag.id
151
+ dragId=drag.id
152
+ onDragEnd=onDragEnd
153
+ )
154
+ Span= drag.text
155
+ `
156
+ ```
157
+
158
+ ## Sandbox
159
+
160
+ ### DragDropProvider
161
+
162
+ <Sandbox
163
+ Component={DragDropProviderSandbox}
164
+ propsJsonSchema={DragDropProviderPropsJsonSchema}
165
+ />
166
+
167
+ ### Droppable
168
+
169
+ <Sandbox
170
+ Component={DroppableSandbox}
171
+ props={{ dropId: 'sandbox-drop' }}
172
+ propsJsonSchema={DroppablePropsJsonSchema}
173
+ />
174
+
175
+ ### Draggable
176
+
177
+ <Sandbox
178
+ Component={DraggableSandbox}
179
+ props={{ dragId: 'sandbox-drag' }}
180
+ propsJsonSchema={DraggablePropsJsonSchema}
181
+ />
@@ -0,0 +1,3 @@
1
+ .placeholder
2
+ background-color var(--color-bg-main-subtle-alt)
3
+ border-radius .5u
package/index.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ /* eslint-disable */
2
+ // DO NOT MODIFY THIS FILE - IT IS AUTOMATICALLY GENERATED ON COMMITS.
3
+
4
+ export { default as DragDropProvider, DragDropContext, type DragDropProviderProps } from './DragDropProvider';
5
+ export { default as Draggable, type DraggableProps, _PropsJsonSchema } from './Draggable';
6
+ export { default as Droppable, type DroppableProps } from './Droppable';
7
+ export { _PropsJsonSchema as DragDropProviderPropsJsonSchema } from './DragDropProvider';
8
+ export { _PropsJsonSchema as DroppablePropsJsonSchema } from './Droppable';
@@ -0,0 +1,15 @@
1
+ .droppable
2
+ margin-right 2u
3
+ background-color var(--color-bg-main-subtle)
4
+ padding 1u
5
+
6
+ .draggable
7
+ width 200px
8
+ background-color var(--color-bg-main-strong)
9
+ margin-top .5u
10
+ margin-bottom .5u
11
+ padding 1u 2u
12
+ border-width 1px
13
+ border-style solid
14
+ border-color var(--color-border-main)
15
+ radius()
package/index.tsx ADDED
@@ -0,0 +1,12 @@
1
+ export {
2
+ default as DragDropProvider,
3
+ DragDropContext,
4
+ type DragDropProviderProps
5
+ } from './DragDropProvider'
6
+
7
+ export { default as Draggable, type DraggableProps, _PropsJsonSchema } from './Draggable'
8
+
9
+ export { default as Droppable, type DroppableProps } from './Droppable'
10
+
11
+ export { _PropsJsonSchema as DragDropProviderPropsJsonSchema } from './DragDropProvider'
12
+ export { _PropsJsonSchema as DroppablePropsJsonSchema } from './Droppable'
package/package.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "@startupjs-ui/draggable",
3
+ "version": "0.1.3",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
7
+ "main": "index.tsx",
8
+ "types": "index.d.ts",
9
+ "type": "module",
10
+ "dependencies": {
11
+ "@startupjs-ui/core": "^0.1.3",
12
+ "@startupjs-ui/portal": "^0.1.3"
13
+ },
14
+ "peerDependencies": {
15
+ "react": "*",
16
+ "react-native": "*",
17
+ "react-native-gesture-handler": "*",
18
+ "startupjs": "*"
19
+ },
20
+ "gitHead": "fd964ebc3892d3dd0a6c85438c0af619cc50c3f0"
21
+ }