@themeable/layout 1.0.3 → 1.0.6
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/EnviroSniffer.js +2 -4
- package/dist/Provider/Layout.d.ts +0 -14
- package/dist/Provider/Layout.js +56 -35
- package/dist/Provider/index.d.ts +16 -6
- package/dist/Provider/index.js +47 -19
- package/dist/Stack/HStack.js +2 -2
- package/dist/Stack/VStack.js +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/EnviroSniffer.tsx +2 -4
- package/src/Provider/Layout.tsx +55 -55
- package/src/Provider/index.tsx +70 -29
- package/src/Stack/HStack.tsx +3 -3
- package/src/Stack/VStack.tsx +3 -3
- package/src/index.ts +2 -1
package/dist/EnviroSniffer.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import { useLayout } from "./Provider/Layout";
|
|
2
|
+
import { useLayout } from "./Provider";
|
|
4
3
|
export var EnviroSniffer = function () {
|
|
5
|
-
var
|
|
6
|
-
var browserViewport = useThemeableLayout().browserViewport;
|
|
4
|
+
var _a = useLayout(), viewSize = _a.viewSize, browserViewport = _a.browserViewport;
|
|
7
5
|
return (React.createElement(React.Fragment, null,
|
|
8
6
|
React.createElement("p", null,
|
|
9
7
|
"Browser size: ",
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
type ViewSize = 'compact' | 'medium' | 'expanded';
|
|
3
|
-
type ViewSizeLimit = 'compact' | 'medium';
|
|
4
|
-
type SpacingContextValue = {
|
|
5
|
-
spacingMode?: 'normal' | 'grouped';
|
|
6
|
-
setMaxViewSize?: ViewSizeLimit;
|
|
7
|
-
viewSize?: ViewSize;
|
|
8
|
-
};
|
|
9
|
-
export declare const Modifier: ({ setMaxViewSize: localSetMaxViewSize, children, }: {
|
|
10
|
-
setMaxViewSize?: ViewSizeLimit;
|
|
11
|
-
children: React.ReactNode;
|
|
12
|
-
}) => React.JSX.Element;
|
|
13
|
-
export declare const useLayout: () => SpacingContextValue;
|
|
14
|
-
export {};
|
package/dist/Provider/Layout.js
CHANGED
|
@@ -1,35 +1,56 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
//
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
// import React, { createContext, useContext } from 'react';
|
|
3
|
+
// import { useThemeableLayout } from './index';
|
|
4
|
+
//
|
|
5
|
+
// type ViewSize = 'compact' | 'medium' | 'expanded';
|
|
6
|
+
// type ViewSizeLimit = 'compact' | 'medium';
|
|
7
|
+
//
|
|
8
|
+
// type SpacingContextValue = {
|
|
9
|
+
// spacingMode?: 'normal' | 'grouped';
|
|
10
|
+
// setMaxViewSize?: ViewSizeLimit;
|
|
11
|
+
// viewSize?: ViewSize;
|
|
12
|
+
// };
|
|
13
|
+
//
|
|
14
|
+
// const clampViewSize = (
|
|
15
|
+
// actual: ViewSize,
|
|
16
|
+
// limit?: ViewSizeLimit
|
|
17
|
+
// ): ViewSize => {
|
|
18
|
+
// if (!limit) return actual;
|
|
19
|
+
// if (limit === 'compact') return 'compact';
|
|
20
|
+
// return actual === 'compact' ? 'compact' : 'medium';
|
|
21
|
+
// };
|
|
22
|
+
//
|
|
23
|
+
// // @ts-ignore
|
|
24
|
+
// const TokenContext = createContext<SpacingContextValue>({});
|
|
25
|
+
//
|
|
26
|
+
// export const Modifier = ({
|
|
27
|
+
// setMaxViewSize: localSetMaxViewSize,
|
|
28
|
+
// children,
|
|
29
|
+
// }: {
|
|
30
|
+
// setMaxViewSize?: ViewSizeLimit;
|
|
31
|
+
// children: React.ReactNode;
|
|
32
|
+
// }) => {
|
|
33
|
+
// const parent = useContext(TokenContext);
|
|
34
|
+
// const { browserViewport } = useThemeableLayout();
|
|
35
|
+
//
|
|
36
|
+
// // Inherit from parent if not provided locally
|
|
37
|
+
// const inheritedSetMaxViewSize = localSetMaxViewSize ?? parent.setMaxViewSize;
|
|
38
|
+
//
|
|
39
|
+
// const maxViewSize = clampViewSize(browserViewport || 'expanded', inheritedSetMaxViewSize);
|
|
40
|
+
//
|
|
41
|
+
// const value: SpacingContextValue = {
|
|
42
|
+
// ...parent,
|
|
43
|
+
// setMaxViewSize: inheritedSetMaxViewSize,
|
|
44
|
+
// viewSize: maxViewSize,
|
|
45
|
+
// };
|
|
46
|
+
//
|
|
47
|
+
// return (
|
|
48
|
+
// <TokenContext.Provider value={value}>
|
|
49
|
+
// {children}
|
|
50
|
+
// </TokenContext.Provider>
|
|
51
|
+
// );
|
|
52
|
+
// };
|
|
53
|
+
//
|
|
54
|
+
// export const useLayout = () => {
|
|
55
|
+
// return useContext(TokenContext);
|
|
56
|
+
// };
|
package/dist/Provider/index.d.ts
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
|
|
3
|
-
export
|
|
4
|
-
|
|
2
|
+
export type ViewSize = 'compact' | 'medium' | 'expanded';
|
|
3
|
+
export type ViewSizeLimit = 'compact' | 'medium';
|
|
4
|
+
type LayoutContextValue = {
|
|
5
|
+
browserViewport: ViewSize;
|
|
6
|
+
viewSize: ViewSize;
|
|
7
|
+
setMaxViewSize?: ViewSizeLimit;
|
|
8
|
+
spacingMode?: 'normal' | 'grouped';
|
|
9
|
+
};
|
|
10
|
+
export declare const LayoutProvider: ({ children }: {
|
|
5
11
|
children: React.ReactNode;
|
|
6
|
-
}
|
|
7
|
-
export declare const
|
|
8
|
-
|
|
12
|
+
}) => React.JSX.Element;
|
|
13
|
+
export declare const LayoutModifier: ({ setMaxViewSize: localSetMaxViewSize, spacingMode, children, }: {
|
|
14
|
+
setMaxViewSize?: ViewSizeLimit;
|
|
15
|
+
spacingMode?: "normal" | "grouped";
|
|
16
|
+
children: React.ReactNode;
|
|
17
|
+
}) => React.JSX.Element;
|
|
18
|
+
export declare const useLayout: () => LayoutContextValue;
|
|
9
19
|
export {};
|
package/dist/Provider/index.js
CHANGED
|
@@ -1,37 +1,65 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
import React, { createContext, useContext, useState, useEffect, useMemo } from 'react';
|
|
13
|
+
// --- Helper ---
|
|
14
|
+
var clampViewSize = function (actual, limit) {
|
|
15
|
+
if (!limit)
|
|
16
|
+
return actual;
|
|
17
|
+
if (limit === 'compact')
|
|
18
|
+
return 'compact';
|
|
19
|
+
return actual === 'expanded' ? 'medium' : actual; // If expanded, lock to medium
|
|
20
|
+
};
|
|
21
|
+
// 1. Single Context with a safe default value fallback
|
|
22
|
+
var LayoutContext = createContext(null);
|
|
23
|
+
// 2. Root Provider: Handles the window resizing logic
|
|
3
24
|
export var LayoutProvider = function (_a) {
|
|
4
25
|
var children = _a.children;
|
|
5
26
|
var _b = useState('compact'), browserViewport = _b[0], setBrowserViewport = _b[1];
|
|
6
|
-
var prefResponsive = {
|
|
7
|
-
medium: 600,
|
|
8
|
-
expanded: 1200
|
|
9
|
-
};
|
|
10
27
|
useEffect(function () {
|
|
28
|
+
var breakpoints = { medium: 600, expanded: 1200 };
|
|
11
29
|
var updateViewportSize = function () {
|
|
12
30
|
var width = window.innerWidth;
|
|
13
|
-
if (width >
|
|
31
|
+
if (width > breakpoints.expanded)
|
|
14
32
|
setBrowserViewport('expanded');
|
|
15
|
-
|
|
16
|
-
else if (width > prefResponsive.medium) {
|
|
33
|
+
else if (width > breakpoints.medium)
|
|
17
34
|
setBrowserViewport('medium');
|
|
18
|
-
|
|
19
|
-
else {
|
|
35
|
+
else
|
|
20
36
|
setBrowserViewport('compact');
|
|
21
|
-
}
|
|
22
37
|
};
|
|
23
38
|
updateViewportSize();
|
|
24
39
|
window.addEventListener('resize', updateViewportSize);
|
|
25
40
|
return function () { return window.removeEventListener('resize', updateViewportSize); };
|
|
26
|
-
}, [
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
41
|
+
}, []);
|
|
42
|
+
// By default, viewSize mirrors browserViewport at the root level
|
|
43
|
+
var value = useMemo(function () { return ({
|
|
44
|
+
browserViewport: browserViewport,
|
|
45
|
+
viewSize: browserViewport,
|
|
46
|
+
}); }, [browserViewport]);
|
|
47
|
+
return (React.createElement(LayoutContext.Provider, { value: value }, children));
|
|
48
|
+
};
|
|
49
|
+
// 3. Modifier: Nested anywhere to constrain or modify the current layout state
|
|
50
|
+
export var LayoutModifier = function (_a) {
|
|
51
|
+
var localSetMaxViewSize = _a.setMaxViewSize, spacingMode = _a.spacingMode, children = _a.children;
|
|
52
|
+
var parent = useLayout(); // Inherit from nearest parent context
|
|
53
|
+
var inheritedSetMaxViewSize = localSetMaxViewSize !== null && localSetMaxViewSize !== void 0 ? localSetMaxViewSize : parent.setMaxViewSize;
|
|
54
|
+
var maxViewSize = clampViewSize(parent.browserViewport, inheritedSetMaxViewSize);
|
|
55
|
+
var value = useMemo(function () { return (__assign(__assign({}, parent), { spacingMode: spacingMode !== null && spacingMode !== void 0 ? spacingMode : parent.spacingMode, setMaxViewSize: inheritedSetMaxViewSize, viewSize: maxViewSize })); }, [parent, inheritedSetMaxViewSize, maxViewSize, spacingMode]);
|
|
56
|
+
return (React.createElement(LayoutContext.Provider, { value: value }, children));
|
|
30
57
|
};
|
|
31
|
-
|
|
32
|
-
|
|
58
|
+
// 4. Consolidated Hook
|
|
59
|
+
export var useLayout = function () {
|
|
60
|
+
var context = useContext(LayoutContext);
|
|
33
61
|
if (!context) {
|
|
34
|
-
throw new Error('
|
|
62
|
+
throw new Error('useLayout must be used within a LayoutProvider');
|
|
35
63
|
}
|
|
36
64
|
return context;
|
|
37
65
|
};
|
package/dist/Stack/HStack.js
CHANGED
|
@@ -12,7 +12,7 @@ var __assign = (this && this.__assign) || function () {
|
|
|
12
12
|
import React, { useMemo } from "react";
|
|
13
13
|
import { generateGridTemplateColumns, showOnSplit } from "./utils";
|
|
14
14
|
import '../../Stack.css';
|
|
15
|
-
import {
|
|
15
|
+
import { LayoutModifier, useLayout } from "../Provider";
|
|
16
16
|
export var HStack = function (_a) {
|
|
17
17
|
var style = _a.style, _b = _a.maxWidth, maxWidth = _b === void 0 ? undefined : _b, children = _a.children, className = _a.className, align = _a.align, showOn = _a.showOn, _c = _a.padding, padding = _c === void 0 ? false : _c, gridExpanded = _a.gridExpanded, gridMedium = _a.gridMedium, gridCompact = _a.gridCompact, ref = _a.ref, _d = _a.width, width = _d === void 0 ? 'fill' : _d, _e = _a.height, height = _e === void 0 ? 'hug' : _e, wrap = _a.wrap, _f = _a.sectionSpacing, sectionSpacing = _f === void 0 ? false : _f, _g = _a.group, group = _g === void 0 ? false : _g, setMaxViewSize = _a.setMaxViewSize;
|
|
18
18
|
var viewSize = useLayout().viewSize;
|
|
@@ -65,7 +65,7 @@ export var HStack = function (_a) {
|
|
|
65
65
|
.join(' ');
|
|
66
66
|
var content = (React.createElement("div", { ref: ref, style: hstackStyles, className: classes }, children));
|
|
67
67
|
if (setMaxViewSize === 'medium' || setMaxViewSize === 'compact') {
|
|
68
|
-
return (React.createElement(
|
|
68
|
+
return (React.createElement(LayoutModifier, { setMaxViewSize: setMaxViewSize }, content));
|
|
69
69
|
}
|
|
70
70
|
return content;
|
|
71
71
|
};
|
package/dist/Stack/VStack.js
CHANGED
|
@@ -13,7 +13,7 @@ import React, { forwardRef, useRef, useImperativeHandle } from "react";
|
|
|
13
13
|
// import { useViewportSize, ViewportSizeProvider } from "../ProviderResponsive";
|
|
14
14
|
import { showOnSplit } from "./utils";
|
|
15
15
|
import '../../Stack.css';
|
|
16
|
-
import {
|
|
16
|
+
import { LayoutModifier, useLayout } from "../Provider/index";
|
|
17
17
|
export var VStack = forwardRef(function (_a, parentRef) {
|
|
18
18
|
var style = _a.style, maxWidth = _a.maxWidth, children = _a.children, className = _a.className, align = _a.align, showOn = _a.showOn, _b = _a.padding, padding = _b === void 0 ? false : _b, _c = _a.height, height = _c === void 0 ? 'hug' : _c, _d = _a.width, width = _d === void 0 ? 'fill' : _d, scroll = _a.scroll, _e = _a.group, group = _e === void 0 ? false : _e, setMaxViewSize = _a.setMaxViewSize;
|
|
19
19
|
var localRef = useRef(null);
|
|
@@ -35,7 +35,7 @@ export var VStack = forwardRef(function (_a, parentRef) {
|
|
|
35
35
|
viewSize,
|
|
36
36
|
children));
|
|
37
37
|
if (setMaxViewSize === 'medium' || setMaxViewSize === 'compact') {
|
|
38
|
-
return (React.createElement(
|
|
38
|
+
return (React.createElement(LayoutModifier, { setMaxViewSize: setMaxViewSize || 'compact' }, content));
|
|
39
39
|
}
|
|
40
40
|
return content;
|
|
41
41
|
});
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/package.json
CHANGED
package/src/EnviroSniffer.tsx
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import { useLayout } from "./Provider/Layout";
|
|
2
|
+
import { useLayout } from "./Provider";
|
|
4
3
|
|
|
5
4
|
export const EnviroSniffer = () => {
|
|
6
5
|
|
|
7
|
-
const { viewSize } = useLayout();
|
|
8
|
-
const { browserViewport } = useThemeableLayout()
|
|
6
|
+
const { viewSize, browserViewport } = useLayout();
|
|
9
7
|
return (
|
|
10
8
|
<>
|
|
11
9
|
<p>Browser size: {browserViewport}</p>
|
package/src/Provider/Layout.tsx
CHANGED
|
@@ -1,55 +1,55 @@
|
|
|
1
|
-
import React, { createContext, useContext } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
type ViewSize = 'compact' | 'medium' | 'expanded';
|
|
5
|
-
type ViewSizeLimit = 'compact' | 'medium';
|
|
6
|
-
|
|
7
|
-
type SpacingContextValue = {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
const clampViewSize = (
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
): ViewSize => {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
// @ts-ignore
|
|
23
|
-
const TokenContext = createContext<SpacingContextValue>({});
|
|
24
|
-
|
|
25
|
-
export const Modifier = ({
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}: {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}) => {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
export const useLayout = () => {
|
|
54
|
-
|
|
55
|
-
};
|
|
1
|
+
// import React, { createContext, useContext } from 'react';
|
|
2
|
+
// import { useThemeableLayout } from './index';
|
|
3
|
+
//
|
|
4
|
+
// type ViewSize = 'compact' | 'medium' | 'expanded';
|
|
5
|
+
// type ViewSizeLimit = 'compact' | 'medium';
|
|
6
|
+
//
|
|
7
|
+
// type SpacingContextValue = {
|
|
8
|
+
// spacingMode?: 'normal' | 'grouped';
|
|
9
|
+
// setMaxViewSize?: ViewSizeLimit;
|
|
10
|
+
// viewSize?: ViewSize;
|
|
11
|
+
// };
|
|
12
|
+
//
|
|
13
|
+
// const clampViewSize = (
|
|
14
|
+
// actual: ViewSize,
|
|
15
|
+
// limit?: ViewSizeLimit
|
|
16
|
+
// ): ViewSize => {
|
|
17
|
+
// if (!limit) return actual;
|
|
18
|
+
// if (limit === 'compact') return 'compact';
|
|
19
|
+
// return actual === 'compact' ? 'compact' : 'medium';
|
|
20
|
+
// };
|
|
21
|
+
//
|
|
22
|
+
// // @ts-ignore
|
|
23
|
+
// const TokenContext = createContext<SpacingContextValue>({});
|
|
24
|
+
//
|
|
25
|
+
// export const Modifier = ({
|
|
26
|
+
// setMaxViewSize: localSetMaxViewSize,
|
|
27
|
+
// children,
|
|
28
|
+
// }: {
|
|
29
|
+
// setMaxViewSize?: ViewSizeLimit;
|
|
30
|
+
// children: React.ReactNode;
|
|
31
|
+
// }) => {
|
|
32
|
+
// const parent = useContext(TokenContext);
|
|
33
|
+
// const { browserViewport } = useThemeableLayout();
|
|
34
|
+
//
|
|
35
|
+
// // Inherit from parent if not provided locally
|
|
36
|
+
// const inheritedSetMaxViewSize = localSetMaxViewSize ?? parent.setMaxViewSize;
|
|
37
|
+
//
|
|
38
|
+
// const maxViewSize = clampViewSize(browserViewport || 'expanded', inheritedSetMaxViewSize);
|
|
39
|
+
//
|
|
40
|
+
// const value: SpacingContextValue = {
|
|
41
|
+
// ...parent,
|
|
42
|
+
// setMaxViewSize: inheritedSetMaxViewSize,
|
|
43
|
+
// viewSize: maxViewSize,
|
|
44
|
+
// };
|
|
45
|
+
//
|
|
46
|
+
// return (
|
|
47
|
+
// <TokenContext.Provider value={value}>
|
|
48
|
+
// {children}
|
|
49
|
+
// </TokenContext.Provider>
|
|
50
|
+
// );
|
|
51
|
+
// };
|
|
52
|
+
//
|
|
53
|
+
// export const useLayout = () => {
|
|
54
|
+
// return useContext(TokenContext);
|
|
55
|
+
// };
|
package/src/Provider/index.tsx
CHANGED
|
@@ -1,51 +1,92 @@
|
|
|
1
|
-
import React, { createContext, useContext, useState, useEffect } from 'react';
|
|
2
|
-
import { Theme } from "./types"
|
|
1
|
+
import React, { createContext, useContext, useState, useEffect, useMemo } from 'react';
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
// --- Types ---
|
|
4
|
+
export type ViewSize = 'compact' | 'medium' | 'expanded';
|
|
5
|
+
export type ViewSizeLimit = 'compact' | 'medium';
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
type LayoutContextValue = {
|
|
8
|
+
browserViewport: ViewSize; // Always guaranteed
|
|
9
|
+
viewSize: ViewSize; // Adjusted by modifiers, defaults to browserViewport
|
|
10
|
+
setMaxViewSize?: ViewSizeLimit;
|
|
11
|
+
spacingMode?: 'normal' | 'grouped';
|
|
12
|
+
};
|
|
9
13
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
// --- Helper ---
|
|
15
|
+
const clampViewSize = (actual: ViewSize, limit?: ViewSizeLimit): ViewSize => {
|
|
16
|
+
if (!limit) return actual;
|
|
17
|
+
if (limit === 'compact') return 'compact';
|
|
18
|
+
return actual === 'expanded' ? 'medium' : actual; // If expanded, lock to medium
|
|
19
|
+
};
|
|
13
20
|
|
|
14
|
-
|
|
21
|
+
// 1. Single Context with a safe default value fallback
|
|
22
|
+
const LayoutContext = createContext<LayoutContextValue | null>(null);
|
|
23
|
+
|
|
24
|
+
// 2. Root Provider: Handles the window resizing logic
|
|
25
|
+
export const LayoutProvider = ({ children }: { children: React.ReactNode }) => {
|
|
26
|
+
const [browserViewport, setBrowserViewport] = useState<ViewSize>('compact');
|
|
15
27
|
|
|
16
|
-
const prefResponsive = {
|
|
17
|
-
medium: 600,
|
|
18
|
-
expanded: 1200
|
|
19
|
-
}
|
|
20
28
|
useEffect(() => {
|
|
29
|
+
const breakpoints = { medium: 600, expanded: 1200 };
|
|
30
|
+
|
|
21
31
|
const updateViewportSize = () => {
|
|
22
32
|
const width = window.innerWidth;
|
|
23
|
-
if (width >
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
setBrowserViewport('medium');
|
|
27
|
-
} else {
|
|
28
|
-
setBrowserViewport('compact');
|
|
29
|
-
}
|
|
33
|
+
if (width > breakpoints.expanded) setBrowserViewport('expanded');
|
|
34
|
+
else if (width > breakpoints.medium) setBrowserViewport('medium');
|
|
35
|
+
else setBrowserViewport('compact');
|
|
30
36
|
};
|
|
37
|
+
|
|
31
38
|
updateViewportSize();
|
|
32
39
|
window.addEventListener('resize', updateViewportSize);
|
|
33
40
|
return () => window.removeEventListener('resize', updateViewportSize);
|
|
34
|
-
}, [
|
|
41
|
+
}, []);
|
|
42
|
+
|
|
43
|
+
// By default, viewSize mirrors browserViewport at the root level
|
|
44
|
+
const value = useMemo(() => ({
|
|
45
|
+
browserViewport,
|
|
46
|
+
viewSize: browserViewport,
|
|
47
|
+
}), [browserViewport]);
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<LayoutContext.Provider value={value}>
|
|
51
|
+
{children}
|
|
52
|
+
</LayoutContext.Provider>
|
|
53
|
+
);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// 3. Modifier: Nested anywhere to constrain or modify the current layout state
|
|
57
|
+
export const LayoutModifier = ({
|
|
58
|
+
setMaxViewSize: localSetMaxViewSize,
|
|
59
|
+
spacingMode,
|
|
60
|
+
children,
|
|
61
|
+
}: {
|
|
62
|
+
setMaxViewSize?: ViewSizeLimit;
|
|
63
|
+
spacingMode?: 'normal' | 'grouped';
|
|
64
|
+
children: React.ReactNode;
|
|
65
|
+
}) => {
|
|
66
|
+
const parent = useLayout(); // Inherit from nearest parent context
|
|
67
|
+
|
|
68
|
+
const inheritedSetMaxViewSize = localSetMaxViewSize ?? parent.setMaxViewSize;
|
|
69
|
+
const maxViewSize = clampViewSize(parent.browserViewport, inheritedSetMaxViewSize);
|
|
70
|
+
|
|
71
|
+
const value = useMemo(() => ({
|
|
72
|
+
...parent,
|
|
73
|
+
spacingMode: spacingMode ?? parent.spacingMode,
|
|
74
|
+
setMaxViewSize: inheritedSetMaxViewSize,
|
|
75
|
+
viewSize: maxViewSize,
|
|
76
|
+
}), [parent, inheritedSetMaxViewSize, maxViewSize, spacingMode]);
|
|
35
77
|
|
|
36
78
|
return (
|
|
37
|
-
<
|
|
38
|
-
browserViewport
|
|
39
|
-
}}>
|
|
79
|
+
<LayoutContext.Provider value={value}>
|
|
40
80
|
{children}
|
|
41
|
-
</
|
|
81
|
+
</LayoutContext.Provider>
|
|
42
82
|
);
|
|
43
83
|
};
|
|
44
84
|
|
|
45
|
-
|
|
46
|
-
|
|
85
|
+
// 4. Consolidated Hook
|
|
86
|
+
export const useLayout = () => {
|
|
87
|
+
const context = useContext(LayoutContext);
|
|
47
88
|
if (!context) {
|
|
48
|
-
throw new Error('
|
|
89
|
+
throw new Error('useLayout must be used within a LayoutProvider');
|
|
49
90
|
}
|
|
50
91
|
return context;
|
|
51
92
|
};
|
package/src/Stack/HStack.tsx
CHANGED
|
@@ -2,7 +2,7 @@ import React, { useMemo } from "react";
|
|
|
2
2
|
import { generateGridTemplateColumns, showOnSplit } from "./utils";
|
|
3
3
|
import { HStackProps } from "./types";
|
|
4
4
|
import '../../Stack.css';
|
|
5
|
-
import {
|
|
5
|
+
import { LayoutModifier, useLayout } from "../Provider";
|
|
6
6
|
|
|
7
7
|
export const HStack: React.FC<HStackProps> = ({
|
|
8
8
|
style,
|
|
@@ -96,9 +96,9 @@ export const HStack: React.FC<HStackProps> = ({
|
|
|
96
96
|
|
|
97
97
|
if (setMaxViewSize === 'medium' || setMaxViewSize === 'compact') {
|
|
98
98
|
return (
|
|
99
|
-
<
|
|
99
|
+
<LayoutModifier setMaxViewSize={setMaxViewSize}>
|
|
100
100
|
{content}
|
|
101
|
-
</
|
|
101
|
+
</LayoutModifier>
|
|
102
102
|
);
|
|
103
103
|
}
|
|
104
104
|
|
package/src/Stack/VStack.tsx
CHANGED
|
@@ -3,7 +3,7 @@ import { VStackProps } from "./types";
|
|
|
3
3
|
// import { useViewportSize, ViewportSizeProvider } from "../ProviderResponsive";
|
|
4
4
|
import { showOnSplit } from "./utils";
|
|
5
5
|
import '../../Stack.css';
|
|
6
|
-
import {
|
|
6
|
+
import { LayoutModifier, useLayout } from "../Provider/index";
|
|
7
7
|
|
|
8
8
|
export const VStack = forwardRef<HTMLDivElement, VStackProps>(
|
|
9
9
|
({
|
|
@@ -60,9 +60,9 @@ export const VStack = forwardRef<HTMLDivElement, VStackProps>(
|
|
|
60
60
|
|
|
61
61
|
if (setMaxViewSize === 'medium' || setMaxViewSize === 'compact') {
|
|
62
62
|
return (
|
|
63
|
-
<
|
|
63
|
+
<LayoutModifier setMaxViewSize={setMaxViewSize || 'compact'}>
|
|
64
64
|
{content}
|
|
65
|
-
</
|
|
65
|
+
</LayoutModifier>
|
|
66
66
|
);
|
|
67
67
|
}
|
|
68
68
|
|
package/src/index.ts
CHANGED