@threlte/flex 0.0.6 → 0.0.7
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/Box/Box.svelte +15 -2
- package/dist/Box/Box.svelte.d.ts +7 -1
- package/dist/Flex/Flex.svelte +7 -1
- package/dist/Flex/Flex.svelte.d.ts +2 -0
- package/dist/Flex/InnerFlex.svelte +23 -10
- package/dist/Flex/InnerFlex.svelte.d.ts +2 -0
- package/dist/Flex/context.d.ts +1 -1
- package/dist/hooks/useDimensions.d.ts +50 -0
- package/dist/hooks/useDimensions.js +59 -0
- package/dist/hooks/useReflow.d.ts +10 -0
- package/dist/hooks/useReflow.js +18 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/package.json +3 -3
package/dist/Box/Box.svelte
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
|
-
<script>import { HierarchicalObject, T } from '@threlte/core';
|
|
1
|
+
<script>import { HierarchicalObject, T, createRawEventDispatcher } from '@threlte/core';
|
|
2
2
|
import { onDestroy } from 'svelte';
|
|
3
3
|
import { Group } from 'three';
|
|
4
4
|
import { useFlex } from '../Flex/context';
|
|
5
5
|
import { createNodeContext } from '../nodes/context';
|
|
6
|
+
import { createUseDimensionsContext } from '../hooks/useDimensions';
|
|
6
7
|
export let order = undefined;
|
|
7
8
|
let _class = '';
|
|
8
9
|
export { _class as class };
|
|
9
|
-
const
|
|
10
|
+
const dispatch = createRawEventDispatcher();
|
|
11
|
+
/**
|
|
12
|
+
* Create the context for `useDimensions`
|
|
13
|
+
*/
|
|
14
|
+
const dimensionsContext = createUseDimensionsContext();
|
|
15
|
+
const { scaleFactor, onEvent, addNode, removeNode, updateNodeProps, mainAxis, crossAxis, depthAxis, classParser, reflow } = useFlex();
|
|
10
16
|
export const group = new Group();
|
|
11
17
|
export const contentGroup = new Group();
|
|
12
18
|
group.userData.isNode = true;
|
|
@@ -38,6 +44,12 @@ onEvent('reflow:after', () => {
|
|
|
38
44
|
getContentGroup().position[$mainAxis] = computedWidth / 2;
|
|
39
45
|
getContentGroup().position[$crossAxis] = -computedHeight / 2;
|
|
40
46
|
getContentGroup().position[$depthAxis] = 0;
|
|
47
|
+
dimensionsContext.width.set(computedWidth);
|
|
48
|
+
dimensionsContext.height.set(computedHeight);
|
|
49
|
+
dispatch('reflow', {
|
|
50
|
+
width: computedWidth,
|
|
51
|
+
height: computedHeight
|
|
52
|
+
});
|
|
41
53
|
});
|
|
42
54
|
</script>
|
|
43
55
|
|
|
@@ -62,6 +74,7 @@ onEvent('reflow:after', () => {
|
|
|
62
74
|
}}
|
|
63
75
|
>
|
|
64
76
|
<slot
|
|
77
|
+
{reflow}
|
|
65
78
|
width={computedWidth}
|
|
66
79
|
height={computedHeight}
|
|
67
80
|
/>
|
package/dist/Box/Box.svelte.d.ts
CHANGED
|
@@ -6,10 +6,16 @@ type BoxProps = NodeProps & {
|
|
|
6
6
|
class?: string
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
type BoxEvents = {
|
|
9
|
+
type BoxEvents = {
|
|
10
|
+
reflow: {
|
|
11
|
+
width: number
|
|
12
|
+
height: number
|
|
13
|
+
}
|
|
14
|
+
}
|
|
10
15
|
|
|
11
16
|
type BoxSlots = {
|
|
12
17
|
default: {
|
|
18
|
+
reflow: () => void
|
|
13
19
|
width: number
|
|
14
20
|
height: number
|
|
15
21
|
}
|
package/dist/Flex/Flex.svelte
CHANGED
|
@@ -8,6 +8,7 @@ import { getRootShift } from '../lib/getRootShift';
|
|
|
8
8
|
import { applyNodeProps } from '../lib/props';
|
|
9
9
|
import { createNodeContext } from '../nodes/context';
|
|
10
10
|
import { createFlexContext } from './context';
|
|
11
|
+
import { createUseDimensionsContext } from '../hooks/useDimensions';
|
|
11
12
|
export let yoga;
|
|
12
13
|
export let width = 1;
|
|
13
14
|
export let height = 1;
|
|
@@ -22,6 +23,10 @@ const rootGroup = new Group();
|
|
|
22
23
|
rootGroup.userData.isNode = true;
|
|
23
24
|
const boundingBox = new Box3();
|
|
24
25
|
const vec3 = new Vector3();
|
|
26
|
+
/**
|
|
27
|
+
* Create the context for `useDimensions`
|
|
28
|
+
*/
|
|
29
|
+
const { width: computedWidth, height: computedHeight } = createUseDimensionsContext();
|
|
25
30
|
/**
|
|
26
31
|
* Reflowing inside useFrame automatically batches reflows to 1 per frame.
|
|
27
32
|
*/
|
|
@@ -68,9 +73,11 @@ const { start: reflow, stop } = useFrame(() => {
|
|
|
68
73
|
maxY = Math.max(maxY, top + height);
|
|
69
74
|
}
|
|
70
75
|
flexContext.emit('reflow:after');
|
|
76
|
+
computedWidth.set((maxX - minX) / scaleFactor);
|
|
77
|
+
computedHeight.set((maxY - minY) / scaleFactor);
|
|
71
78
|
dispatch('reflow', {
|
|
72
|
-
width:
|
|
73
|
-
height:
|
|
79
|
+
width: computedWidth.current,
|
|
80
|
+
height: computedHeight.current
|
|
74
81
|
});
|
|
75
82
|
stop();
|
|
76
83
|
}, { autostart: false });
|
|
@@ -120,19 +127,25 @@ const flexContext = createFlexContext({
|
|
|
120
127
|
const { mainAxis, crossAxis, depthAxis } = flexContext;
|
|
121
128
|
const { node: rootNode } = createNodeContext();
|
|
122
129
|
$: rootNode.setWidth(width * scaleFactor), rootNode.setHeight(height * scaleFactor);
|
|
123
|
-
$:
|
|
130
|
+
$: {
|
|
131
|
+
applyNodeProps(rootNode, { ...classParser?.(_class, {}), ...$$restProps }, scaleFactor);
|
|
124
132
|
reflow();
|
|
125
|
-
|
|
126
|
-
$: flexContext.
|
|
127
|
-
$: flexContext.
|
|
128
|
-
$: flexContext.
|
|
129
|
-
$: flexContext.
|
|
130
|
-
$: flexContext.
|
|
133
|
+
}
|
|
134
|
+
$: flexContext.rootWidth.set(width), flexContext.reflow();
|
|
135
|
+
$: flexContext.rootHeight.set(height), flexContext.reflow();
|
|
136
|
+
$: flexContext.mainAxis.set(plane[0]), flexContext.reflow();
|
|
137
|
+
$: flexContext.crossAxis.set(plane[1]), flexContext.reflow();
|
|
138
|
+
$: flexContext.depthAxis.set(getDepthAxis(plane)), flexContext.reflow();
|
|
139
|
+
$: flexContext.scaleFactor.set(scaleFactor), flexContext.reflow();
|
|
131
140
|
onDestroy(() => {
|
|
132
141
|
rootNode.free();
|
|
133
142
|
});
|
|
134
143
|
</script>
|
|
135
144
|
|
|
136
145
|
<T is={rootGroup}>
|
|
137
|
-
<slot
|
|
146
|
+
<slot
|
|
147
|
+
{reflow}
|
|
148
|
+
width={$computedWidth}
|
|
149
|
+
height={$computedHeight}
|
|
150
|
+
/>
|
|
138
151
|
</T>
|
package/dist/Flex/context.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ export type FlexContextData = {
|
|
|
25
25
|
rootGroup: Group;
|
|
26
26
|
rootWidth: CurrentWritable<number>;
|
|
27
27
|
rootHeight: CurrentWritable<number>;
|
|
28
|
-
reflow: (
|
|
28
|
+
reflow: () => void;
|
|
29
29
|
classParser?: ClassParser;
|
|
30
30
|
};
|
|
31
31
|
export type FlexContext = FlexContextData & Emitter<FlexContextEvents> & {
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { type CurrentWritable } from '@threlte/core';
|
|
2
|
+
type UseDimensionsContext = {
|
|
3
|
+
width: CurrentWritable<number>;
|
|
4
|
+
height: CurrentWritable<number>;
|
|
5
|
+
};
|
|
6
|
+
export declare const flexContextName = "__threlte-flex-dimensions";
|
|
7
|
+
/**
|
|
8
|
+
* Creates a context for useDimensions.
|
|
9
|
+
*/
|
|
10
|
+
export declare const createUseDimensionsContext: () => UseDimensionsContext;
|
|
11
|
+
/**
|
|
12
|
+
* The hook `useDimensions` can be used to retrieve the computed width and
|
|
13
|
+
* height of a `<Flex>` or `<Box>` component as
|
|
14
|
+
* [CurrentWritable](https://threlte.xyz/docs/reference/core/utilities#currentwritable)
|
|
15
|
+
* stores.
|
|
16
|
+
*
|
|
17
|
+
* ## Usage
|
|
18
|
+
*
|
|
19
|
+
* ### In a `<Flex>` component
|
|
20
|
+
*
|
|
21
|
+
* Because there's no viewport to measure, the width and height of a `<Flex>`
|
|
22
|
+
* component need to be set manually. Nevertheless, the dimensions of the
|
|
23
|
+
* contents of the `<Flex>` component will be measured after a layout reflow and
|
|
24
|
+
* can be retrieved using `useDimensions` in a direct child component to
|
|
25
|
+
* `<Flex>`.
|
|
26
|
+
*
|
|
27
|
+
* ### In a `<Box>` component
|
|
28
|
+
*
|
|
29
|
+
* By default `@threlte/flex` controls elements position only. In some cases you
|
|
30
|
+
* may want to control element sizing too. Since `@threlte/flex` has no
|
|
31
|
+
* information about how the inner content size works, you need to set your
|
|
32
|
+
* content size manually. You can do this by using `useDimensions` hook in a
|
|
33
|
+
* direct child component to `<Box>`.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```svelte
|
|
37
|
+
* <script>
|
|
38
|
+
* import { useDimensions } from '@threlte/flex'
|
|
39
|
+
*
|
|
40
|
+
* const { width, height } = useDimensions()
|
|
41
|
+
* </script>
|
|
42
|
+
*
|
|
43
|
+
* <T.Mesh scale.x={$width} scale.y={$height}>
|
|
44
|
+
* <T.BoxGeometry />
|
|
45
|
+
* <T.MeshBasicMaterial color="red" />
|
|
46
|
+
* </T.Mesh>
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare const useDimensions: () => UseDimensionsContext;
|
|
50
|
+
export {};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { getContext, setContext } from 'svelte';
|
|
2
|
+
import { currentWritable } from '@threlte/core';
|
|
3
|
+
export const flexContextName = '__threlte-flex-dimensions';
|
|
4
|
+
/**
|
|
5
|
+
* Creates a context for useDimensions.
|
|
6
|
+
*/
|
|
7
|
+
export const createUseDimensionsContext = () => {
|
|
8
|
+
const context = {
|
|
9
|
+
width: currentWritable(0),
|
|
10
|
+
height: currentWritable(0)
|
|
11
|
+
};
|
|
12
|
+
setContext(flexContextName, context);
|
|
13
|
+
return context;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* The hook `useDimensions` can be used to retrieve the computed width and
|
|
17
|
+
* height of a `<Flex>` or `<Box>` component as
|
|
18
|
+
* [CurrentWritable](https://threlte.xyz/docs/reference/core/utilities#currentwritable)
|
|
19
|
+
* stores.
|
|
20
|
+
*
|
|
21
|
+
* ## Usage
|
|
22
|
+
*
|
|
23
|
+
* ### In a `<Flex>` component
|
|
24
|
+
*
|
|
25
|
+
* Because there's no viewport to measure, the width and height of a `<Flex>`
|
|
26
|
+
* component need to be set manually. Nevertheless, the dimensions of the
|
|
27
|
+
* contents of the `<Flex>` component will be measured after a layout reflow and
|
|
28
|
+
* can be retrieved using `useDimensions` in a direct child component to
|
|
29
|
+
* `<Flex>`.
|
|
30
|
+
*
|
|
31
|
+
* ### In a `<Box>` component
|
|
32
|
+
*
|
|
33
|
+
* By default `@threlte/flex` controls elements position only. In some cases you
|
|
34
|
+
* may want to control element sizing too. Since `@threlte/flex` has no
|
|
35
|
+
* information about how the inner content size works, you need to set your
|
|
36
|
+
* content size manually. You can do this by using `useDimensions` hook in a
|
|
37
|
+
* direct child component to `<Box>`.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```svelte
|
|
41
|
+
* <script>
|
|
42
|
+
* import { useDimensions } from '@threlte/flex'
|
|
43
|
+
*
|
|
44
|
+
* const { width, height } = useDimensions()
|
|
45
|
+
* </script>
|
|
46
|
+
*
|
|
47
|
+
* <T.Mesh scale.x={$width} scale.y={$height}>
|
|
48
|
+
* <T.BoxGeometry />
|
|
49
|
+
* <T.MeshBasicMaterial color="red" />
|
|
50
|
+
* </T.Mesh>
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export const useDimensions = () => {
|
|
54
|
+
const context = getContext(flexContextName);
|
|
55
|
+
if (!context) {
|
|
56
|
+
throw new Error('useDimensions must be used within a <Flex> component');
|
|
57
|
+
}
|
|
58
|
+
return context;
|
|
59
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The hook useReflow allows you to manually request a [layout
|
|
3
|
+
* reflow](https://threlte.xyz/docs/reference/flex/flex#layout-reflow), for
|
|
4
|
+
* instance when a [`<Text>`](https://threlte.xyz/docs/reference/extras/text)
|
|
5
|
+
* component finished synchronizing or when a model has loaded into view and
|
|
6
|
+
* there’s no easy access to the reflow slot prop of the components `<Flex>` or
|
|
7
|
+
* `<Box>` because of component composition. Calls to`reflow` will be limited to
|
|
8
|
+
* once per frame, so it’s safe to call it from multiple components at a time.
|
|
9
|
+
*/
|
|
10
|
+
export declare const useReflow: () => () => void;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { getContext } from 'svelte';
|
|
2
|
+
import { flexContextName } from '../Flex/context';
|
|
3
|
+
/**
|
|
4
|
+
* The hook useReflow allows you to manually request a [layout
|
|
5
|
+
* reflow](https://threlte.xyz/docs/reference/flex/flex#layout-reflow), for
|
|
6
|
+
* instance when a [`<Text>`](https://threlte.xyz/docs/reference/extras/text)
|
|
7
|
+
* component finished synchronizing or when a model has loaded into view and
|
|
8
|
+
* there’s no easy access to the reflow slot prop of the components `<Flex>` or
|
|
9
|
+
* `<Box>` because of component composition. Calls to`reflow` will be limited to
|
|
10
|
+
* once per frame, so it’s safe to call it from multiple components at a time.
|
|
11
|
+
*/
|
|
12
|
+
export const useReflow = () => {
|
|
13
|
+
const flexContext = getContext(flexContextName);
|
|
14
|
+
if (!flexContext) {
|
|
15
|
+
throw new Error('useReflow must be used within a <Flex> component');
|
|
16
|
+
}
|
|
17
|
+
return flexContext.reflow;
|
|
18
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -3,3 +3,5 @@ export { default as Flex } from './Flex/Flex.svelte';
|
|
|
3
3
|
export type { NodeProps } from './lib/props';
|
|
4
4
|
export { createClassParser } from './parsers/createClassParser';
|
|
5
5
|
export { tailwindParser } from './parsers/tailwindParser';
|
|
6
|
+
export { useReflow } from './hooks/useReflow';
|
|
7
|
+
export { useDimensions } from './hooks/useDimensions';
|
package/dist/index.js
CHANGED
|
@@ -3,3 +3,6 @@ export { default as Flex } from './Flex/Flex.svelte';
|
|
|
3
3
|
// parsers
|
|
4
4
|
export { createClassParser } from './parsers/createClassParser';
|
|
5
5
|
export { tailwindParser } from './parsers/tailwindParser';
|
|
6
|
+
// hooks
|
|
7
|
+
export { useReflow } from './hooks/useReflow';
|
|
8
|
+
export { useDimensions } from './hooks/useDimensions';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@threlte/flex",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
4
4
|
"author": "Grischa Erbe <hello@legrisch.com> (https://legrisch.com)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"devDependencies": {
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
"tslib": "^2.4.1",
|
|
28
28
|
"typescript": "^5.0.0",
|
|
29
29
|
"vite": "^4.3.6",
|
|
30
|
-
"@threlte/core": "6.0.
|
|
31
|
-
"@threlte/extras": "
|
|
30
|
+
"@threlte/core": "6.0.9",
|
|
31
|
+
"@threlte/extras": "6.0.0"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"mitt": "^3.0.1",
|