@jsenv/navi 0.8.0 → 0.9.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/navi",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "Library of components including navigation to create frontend applications",
5
5
  "repository": {
6
6
  "type": "git",
@@ -14,8 +14,7 @@ import { FormActionContext } from "../action_execution/form_context.js";
14
14
  import { renderActionableComponent } from "../action_execution/render_actionable_component.jsx";
15
15
  import { useAction } from "../action_execution/use_action.js";
16
16
  import { useExecuteAction } from "../action_execution/use_execute_action.js";
17
- import { useConsumAlignProps } from "../layout/flex.jsx";
18
- import { consumeSpacingProps } from "../layout/spacing.jsx";
17
+ import { useLayoutStyle } from "../layout/use_layout_style.js";
19
18
  import { LoaderBackground } from "../loader/loader_background.jsx";
20
19
  import { withPropsClassName } from "../props_composition/with_props_class_name.js";
21
20
  import { withPropsStyle } from "../props_composition/with_props_style.js";
@@ -89,6 +88,7 @@ import.meta.css = /* css */ `
89
88
  .navi_button_content {
90
89
  position: relative;
91
90
  display: inline-flex;
91
+ width: 100%;
92
92
  padding-top: var(--padding-y);
93
93
  padding-right: var(--padding-x);
94
94
  padding-bottom: var(--padding-y);
@@ -212,8 +212,6 @@ const ButtonBasic = forwardRef((props, ref) => {
212
212
 
213
213
  // visual
214
214
  appearance = "navi",
215
- alignX,
216
- alignY,
217
215
  discrete,
218
216
  className,
219
217
  style,
@@ -242,13 +240,8 @@ const ButtonBasic = forwardRef((props, ref) => {
242
240
  appearance === "navi" ? "navi_button" : undefined,
243
241
  className,
244
242
  );
245
- const innerStyle = withPropsStyle(
246
- {
247
- ...consumeSpacingProps(rest),
248
- ...useConsumAlignProps({ alignX, alignY }),
249
- },
250
- style,
251
- );
243
+ const { all } = useLayoutStyle(rest);
244
+ const innerStyle = withPropsStyle(all, style);
252
245
 
253
246
  return (
254
247
  <button
@@ -13,7 +13,7 @@ import { useConstraints } from "../../validation/hooks/use_constraints.js";
13
13
  import { renderActionableComponent } from "../action_execution/render_actionable_component.jsx";
14
14
  import { useActionBoundToOneParam } from "../action_execution/use_action.js";
15
15
  import { useExecuteAction } from "../action_execution/use_execute_action.js";
16
- import { consumeSpacingProps } from "../layout/spacing.jsx";
16
+ import { useLayoutStyle } from "../layout/use_layout_style.js";
17
17
  import {
18
18
  LoadableInlineElement,
19
19
  LoaderBackground,
@@ -333,10 +333,11 @@ const NaviCheckbox = ({
333
333
  return initCustomField(ref.current, inputRef.current);
334
334
  }, []);
335
335
 
336
+ const { all } = useLayoutStyle(rest);
336
337
  const innerStyle = withPropsStyle(
337
338
  {
339
+ ...all,
338
340
  ...(accentColor ? { "--accent-color": accentColor } : {}),
339
- ...consumeSpacingProps(rest),
340
341
  },
341
342
  style,
342
343
  );
@@ -8,7 +8,7 @@ import {
8
8
 
9
9
  import { useConstraints } from "../../validation/hooks/use_constraints.js";
10
10
  import { renderActionableComponent } from "../action_execution/render_actionable_component.jsx";
11
- import { consumeSpacingProps } from "../layout/spacing.jsx";
11
+ import { useLayoutStyle } from "../layout/use_layout_style.js";
12
12
  import {
13
13
  LoadableInlineElement,
14
14
  LoaderBackground,
@@ -372,10 +372,11 @@ const NaviRadio = ({
372
372
  return initCustomField(ref.current, inputRef.current);
373
373
  }, []);
374
374
 
375
+ const { all } = useLayoutStyle(rest);
375
376
  const innerStyle = withPropsStyle(
376
377
  {
378
+ ...all,
377
379
  ...(accentColor ? { "--accent-color": accentColor } : {}),
378
- ...consumeSpacingProps(rest),
379
380
  },
380
381
  style,
381
382
  );
@@ -31,7 +31,7 @@ import { useConstraints } from "../../validation/hooks/use_constraints.js";
31
31
  import { renderActionableComponent } from "../action_execution/render_actionable_component.jsx";
32
32
  import { useActionBoundToOneParam } from "../action_execution/use_action.js";
33
33
  import { useExecuteAction } from "../action_execution/use_execute_action.js";
34
- import { consumeSpacingProps } from "../layout/spacing.jsx";
34
+ import { useLayoutStyle } from "../layout/use_layout_style.js";
35
35
  import { LoadableInlineElement } from "../loader/loader_background.jsx";
36
36
  import { withPropsClassName } from "../props_composition/with_props_class_name.js";
37
37
  import { withPropsStyle } from "../props_composition/with_props_style.js";
@@ -88,6 +88,8 @@ import.meta.css = /* css */ `
88
88
  --color: currentColor;
89
89
  --color-readonly: color-mix(in srgb, currentColor 60%, transparent);
90
90
  --color-disabled: var(--color-readonly);
91
+
92
+ width: 100%;
91
93
  color: var(--color);
92
94
 
93
95
  background-color: var(--background-color);
@@ -170,8 +172,6 @@ const InputTextualBasic = forwardRef((props, ref) => {
170
172
  // visual
171
173
  appearance = "navi",
172
174
  accentColor,
173
- width,
174
- height,
175
175
  className,
176
176
  style,
177
177
 
@@ -199,14 +199,8 @@ const InputTextualBasic = forwardRef((props, ref) => {
199
199
  appearance === "navi" ? "navi_input" : undefined,
200
200
  className,
201
201
  );
202
- const innerStyle = withPropsStyle(
203
- {
204
- width,
205
- height,
206
- ...consumeSpacingProps(rest),
207
- },
208
- style,
209
- );
202
+ const { margin, padding, alignment, expansion } = useLayoutStyle(rest);
203
+ const innerStyle = withPropsStyle(padding, style);
210
204
  const inputTextual = (
211
205
  <input
212
206
  {...rest}
@@ -254,11 +248,12 @@ const InputTextualBasic = forwardRef((props, ref) => {
254
248
  <LoadableInlineElement
255
249
  loading={innerLoading}
256
250
  style={{
251
+ ...margin,
252
+ ...alignment,
253
+ ...expansion,
257
254
  "--accent-color": accentColor || "light-dark(#355fcc, #4476ff)",
258
255
  }}
259
256
  color="var(--accent-color)"
260
- width={width}
261
- height={height}
262
257
  inset={-1}
263
258
  >
264
259
  {inputTextual}
@@ -0,0 +1,226 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <title>useLayoutStyle Demo</title>
6
+ <style>
7
+ .demo-container {
8
+ margin-bottom: 30px;
9
+ padding: 20px;
10
+ background: #f8f9fa;
11
+ border-radius: 8px;
12
+ }
13
+
14
+ .demo-box {
15
+ min-width: 60px;
16
+ padding: 10px;
17
+ text-align: center;
18
+ background: #e3f2fd;
19
+ border: 1px solid #90caf9;
20
+ border-radius: 4px;
21
+ }
22
+
23
+ .visual-container {
24
+ margin: 10px 0;
25
+ padding: 10px;
26
+ background: #fff3e0;
27
+ border: 2px dashed #ff9800;
28
+ }
29
+
30
+ h3 {
31
+ margin-top: 0;
32
+ }
33
+
34
+ /* Helper to visualize the container boundaries */
35
+ .bounded {
36
+ width: 400px;
37
+ height: 100px;
38
+ padding: 10px;
39
+ background: #f0f4ff;
40
+ border: 1px solid #6366f1;
41
+ }
42
+ </style>
43
+ </head>
44
+ <body>
45
+ <div id="app"></div>
46
+ <script type="module" jsenv-type="module/jsx">
47
+ /* eslint-disable no-unused-vars */
48
+ import { render } from "preact";
49
+ import { FlexRow, FlexColumn, Input, Button } from "@jsenv/navi";
50
+
51
+ const DemoBox = ({ children, ...props }) => (
52
+ <div className="demo-box" {...props}>
53
+ {children}
54
+ </div>
55
+ );
56
+
57
+ const Demo = () => {
58
+ return (
59
+ <div style={{ padding: "20px", fontFamily: "system-ui, sans-serif" }}>
60
+ <h1>useLayoutStyle Demo - Input Elements</h1>
61
+ <p>
62
+ Testing spacing (margin/padding), alignment, and expand behavior
63
+ specifically with Input components in various layout contexts.
64
+ </p>
65
+
66
+ <div className="demo-container">
67
+ <h3>1. Input with Expand in FlexRow</h3>
68
+ <div className="visual-container">
69
+ <FlexRow gap="10px">
70
+ <Button>Start</Button>
71
+ <Input placeholder="Expanding input" expand />
72
+ <Button>End</Button>
73
+ </FlexRow>
74
+ </div>
75
+ </div>
76
+
77
+ <div className="demo-container">
78
+ <h3>2. Input with Expand in FlexColumn</h3>
79
+ <div className="visual-container">
80
+ <FlexColumn gap="10px" style={{ height: "200px" }}>
81
+ <Input placeholder="Fixed input" />
82
+ <Input placeholder="Expanding input (height)" expand />
83
+ <Input placeholder="Fixed input" />
84
+ </FlexColumn>
85
+ </div>
86
+ </div>
87
+
88
+ <div className="demo-container">
89
+ <h3>3. Input with Expand outside Flex context</h3>
90
+ <div className="visual-container">
91
+ <div
92
+ style={{
93
+ width: "300px",
94
+ border: "1px solid #ccc",
95
+ padding: "10px",
96
+ }}
97
+ >
98
+ <Input placeholder="Normal input" />
99
+ <br />
100
+ <br />
101
+ <Input
102
+ placeholder="Expanding input (should take full width)"
103
+ expand
104
+ />
105
+ </div>
106
+ </div>
107
+ </div>
108
+
109
+ <div className="demo-container">
110
+ <h3>4. Multiple Expand Elements</h3>
111
+ <div className="visual-container">
112
+ <FlexRow gap="10px">
113
+ <Input placeholder="Expand 1" expand />
114
+ <Input placeholder="Expand 2" expand />
115
+ <Input placeholder="Expand 3" expand />
116
+ </FlexRow>
117
+ </div>
118
+ </div>
119
+
120
+ <div className="demo-container">
121
+ <h3>5. Basic Spacing - Input with margins</h3>
122
+ <div className="visual-container">
123
+ <Input placeholder="Default input" margin="10px" />
124
+ <Input placeholder="MarginX only" marginX="20px" />
125
+ <Input placeholder="MarginY only" marginY="15px" />
126
+ </div>
127
+ </div>
128
+
129
+ <div className="demo-container">
130
+ <h3>6. Input with Padding</h3>
131
+ <div className="visual-container">
132
+ <Input placeholder="Default padding" />
133
+ <Input placeholder="Extra padding" padding="20px" />
134
+ <Input placeholder="PaddingX only" paddingX="30px" />
135
+ </div>
136
+ </div>
137
+
138
+ <div className="demo-container">
139
+ <h3>7. Directional Margins and Padding</h3>
140
+ <div className="visual-container">
141
+ <FlexColumn gap="5px">
142
+ <Input placeholder="marginLeft: 20px" marginLeft="20px" />
143
+ <Input placeholder="marginRight: 30px" marginRight="30px" />
144
+ <Input
145
+ placeholder="marginTop: 15px, marginBottom: 25px"
146
+ marginTop="15px"
147
+ marginBottom="25px"
148
+ />
149
+ <Input placeholder="paddingLeft: 25px" paddingLeft="25px" />
150
+ </FlexColumn>
151
+ </div>
152
+ </div>
153
+
154
+ <div className="demo-container">
155
+ <h3>8. AlignX Test: FlexRow + alignX="end"</h3>
156
+ <div className="visual-container">
157
+ <div className="bounded">
158
+ <FlexRow gap="10px" style={{ height: "100%" }}>
159
+ <Input placeholder="Default" />
160
+ <Input placeholder="Pushed to end" alignX="end" />
161
+ </FlexRow>
162
+ </div>
163
+ </div>
164
+ </div>
165
+
166
+ <div className="demo-container">
167
+ <h3>9. Combined Spacing and Expand</h3>
168
+ <div className="visual-container">
169
+ <FlexRow gap="10px">
170
+ <Button>Label</Button>
171
+ <Input
172
+ placeholder="Margin + Expand"
173
+ expand
174
+ marginY="5px"
175
+ paddingX="15px"
176
+ />
177
+ <Button>Action</Button>
178
+ </FlexRow>
179
+ </div>
180
+ </div>
181
+
182
+ <div className="demo-container">
183
+ <h3>10. Complex Layout: Form with Expand</h3>
184
+ <div className="visual-container">
185
+ <FlexColumn gap="15px">
186
+ <FlexRow gap="10px">
187
+ <label style={{ minWidth: "80px", alignSelf: "center" }}>
188
+ Name:
189
+ </label>
190
+ <Input placeholder="Enter your name" expand />
191
+ </FlexRow>
192
+
193
+ <FlexRow gap="10px">
194
+ <label style={{ minWidth: "80px", alignSelf: "center" }}>
195
+ Email:
196
+ </label>
197
+ <Input placeholder="Enter your email" expand />
198
+ <Button>Verify</Button>
199
+ </FlexRow>
200
+
201
+ <FlexRow gap="10px">
202
+ <label style={{ minWidth: "80px", alignSelf: "center" }}>
203
+ Message:
204
+ </label>
205
+ <Input
206
+ placeholder="Enter your message"
207
+ expand
208
+ paddingY="10px"
209
+ />
210
+ </FlexRow>
211
+
212
+ <FlexRow gap="10px" alignX="end">
213
+ <Button>Cancel</Button>
214
+ <Button>Submit</Button>
215
+ </FlexRow>
216
+ </FlexColumn>
217
+ </div>
218
+ </div>
219
+ </div>
220
+ );
221
+ };
222
+
223
+ render(<Demo />, document.getElementById("app"));
224
+ </script>
225
+ </body>
226
+ </html>
@@ -0,0 +1,260 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <title>useLayoutStyle Demo - Buttons</title>
6
+ <style>
7
+ .demo-container {
8
+ margin-bottom: 30px;
9
+ padding: 20px;
10
+ background: #f8f9fa;
11
+ border-radius: 8px;
12
+ }
13
+
14
+ .demo-box {
15
+ min-width: 60px;
16
+ padding: 10px;
17
+ text-align: center;
18
+ background: #e3f2fd;
19
+ border: 1px solid #90caf9;
20
+ border-radius: 4px;
21
+ }
22
+
23
+ .visual-container {
24
+ margin: 10px 0;
25
+ padding: 10px;
26
+ background: #fff3e0;
27
+ border: 2px dashed #ff9800;
28
+ }
29
+
30
+ h3 {
31
+ margin-top: 0;
32
+ }
33
+
34
+ /* Helper to visualize the container boundaries */
35
+ .bounded {
36
+ width: 400px;
37
+ height: 100px;
38
+ padding: 10px;
39
+ background: #f0f4ff;
40
+ border: 1px solid #6366f1;
41
+ }
42
+ </style>
43
+ </head>
44
+ <body>
45
+ <div id="app"></div>
46
+ <script type="module" jsenv-type="module/jsx">
47
+ /* eslint-disable no-unused-vars */
48
+ import { render } from "preact";
49
+ import { FlexRow, FlexColumn, Input, Button } from "@jsenv/navi";
50
+
51
+ const DemoBox = ({ children, ...props }) => (
52
+ <div className="demo-box" {...props}>
53
+ {children}
54
+ </div>
55
+ );
56
+
57
+ const Demo = () => {
58
+ return (
59
+ <div style={{ padding: "20px", fontFamily: "system-ui, sans-serif" }}>
60
+ <h1>useLayoutStyle Demo - Button Elements</h1>
61
+ <p>
62
+ Testing spacing (margin/padding), alignment, and expand behavior
63
+ specifically with Button components in various layout contexts.
64
+ </p>
65
+
66
+ <div className="demo-container">
67
+ <h3>1. Button with Expand in FlexRow</h3>
68
+ <div className="visual-container">
69
+ <FlexRow gap="10px">
70
+ <Button>Fixed</Button>
71
+ <Button expand>Expanding Button</Button>
72
+ <Button>Fixed</Button>
73
+ </FlexRow>
74
+ </div>
75
+ </div>
76
+
77
+ <div className="demo-container">
78
+ <h3>2. Button with Expand in FlexColumn</h3>
79
+ <div className="visual-container">
80
+ <FlexColumn gap="10px" style={{ height: "200px" }}>
81
+ <Button>Fixed Button</Button>
82
+ <Button expand>Expanding Button (height)</Button>
83
+ <Button>Fixed Button</Button>
84
+ </FlexColumn>
85
+ </div>
86
+ </div>
87
+
88
+ <div className="demo-container">
89
+ <h3>3. Button with Expand outside Flex context</h3>
90
+ <div className="visual-container">
91
+ <div
92
+ style={{
93
+ width: "300px",
94
+ border: "1px solid #ccc",
95
+ padding: "10px",
96
+ }}
97
+ >
98
+ <Button>Normal Button</Button>
99
+ <br />
100
+ <br />
101
+ <Button expand>
102
+ Expanding Button (should take full width)
103
+ </Button>
104
+ </div>
105
+ </div>
106
+ </div>
107
+
108
+ <div className="demo-container">
109
+ <h3>4. Multiple Expand Buttons</h3>
110
+ <div className="visual-container">
111
+ <FlexRow gap="10px">
112
+ <Button expand>Expand 1</Button>
113
+ <Button expand>Expand 2</Button>
114
+ <Button expand>Expand 3</Button>
115
+ </FlexRow>
116
+ </div>
117
+ </div>
118
+
119
+ <div className="demo-container">
120
+ <h3>5. Button Spacing - Margins</h3>
121
+ <div className="visual-container">
122
+ <FlexColumn gap="5px">
123
+ <Button margin="10px">Margin All Sides</Button>
124
+ <Button marginX="20px">MarginX Only</Button>
125
+ <Button marginY="15px">MarginY Only</Button>
126
+ <Button marginLeft="30px">MarginLeft Only</Button>
127
+ <Button marginRight="25px">MarginRight Only</Button>
128
+ </FlexColumn>
129
+ </div>
130
+ </div>
131
+
132
+ <div className="demo-container">
133
+ <h3>6. Button Spacing - Padding</h3>
134
+ <div className="visual-container">
135
+ <FlexColumn gap="5px">
136
+ <Button>Default Padding</Button>
137
+ <Button padding="20px">Extra Padding</Button>
138
+ <Button paddingX="30px">PaddingX Only</Button>
139
+ <Button paddingY="15px">PaddingY Only</Button>
140
+ <Button paddingLeft="25px">PaddingLeft Only</Button>
141
+ </FlexColumn>
142
+ </div>
143
+ </div>
144
+
145
+ <div className="demo-container">
146
+ <h3>7. Button AlignX Test: FlexRow + alignX="end"</h3>
147
+ <div className="visual-container">
148
+ <div className="bounded">
149
+ <FlexRow gap="10px" style={{ height: "100%" }}>
150
+ <Button>Default</Button>
151
+ <Button alignX="end">Pushed to End</Button>
152
+ </FlexRow>
153
+ </div>
154
+ </div>
155
+ </div>
156
+
157
+ <div className="demo-container">
158
+ <h3>8. Combined Spacing and Expand</h3>
159
+ <div className="visual-container">
160
+ <FlexRow gap="10px">
161
+ <Button>Label</Button>
162
+ <Button expand marginY="5px" paddingX="20px">
163
+ Margin + Padding + Expand
164
+ </Button>
165
+ <Button>End</Button>
166
+ </FlexRow>
167
+ </div>
168
+ </div>
169
+
170
+ <div className="demo-container">
171
+ <h3>9. Button Toolbar Layout</h3>
172
+ <div className="visual-container">
173
+ <FlexRow gap="10px">
174
+ <Button>New</Button>
175
+ <Button>Open</Button>
176
+ <Button>Save</Button>
177
+ <Button expand>Status Message Area</Button>
178
+ <Button alignX="end">Settings</Button>
179
+ </FlexRow>
180
+ </div>
181
+ </div>
182
+
183
+ <div className="demo-container">
184
+ <h3>10. Button Group with Various Alignments</h3>
185
+ <div className="visual-container">
186
+ <FlexColumn gap="10px">
187
+ <FlexRow gap="10px">
188
+ <Button>Start</Button>
189
+ <Button alignX="center">Center</Button>
190
+ <Button alignX="end">End</Button>
191
+ </FlexRow>
192
+
193
+ <FlexRow gap="10px">
194
+ <Button expand>Primary Action</Button>
195
+ <Button>Cancel</Button>
196
+ </FlexRow>
197
+
198
+ <FlexRow gap="10px" alignX="end">
199
+ <Button>Back</Button>
200
+ <Button>Next</Button>
201
+ </FlexRow>
202
+ </FlexColumn>
203
+ </div>
204
+ </div>
205
+
206
+ <div className="demo-container">
207
+ <h3>11. Card Layout with Button Actions</h3>
208
+ <div className="visual-container">
209
+ <div
210
+ style={{
211
+ border: "1px solid #ddd",
212
+ borderRadius: "8px",
213
+ padding: "20px",
214
+ width: "350px",
215
+ }}
216
+ >
217
+ <h4 style={{ margin: "0 0 10px 0" }}>Card Title</h4>
218
+ <p style={{ margin: "0 0 20px 0", color: "#666" }}>
219
+ This is some card content that describes the item or action.
220
+ </p>
221
+
222
+ <FlexRow gap="10px">
223
+ <Button expand>Primary Action</Button>
224
+ <Button alignX="end">More</Button>
225
+ </FlexRow>
226
+ </div>
227
+ </div>
228
+ </div>
229
+
230
+ <div className="demo-container">
231
+ <h3>12. Navigation Button Layout</h3>
232
+ <div className="visual-container">
233
+ <FlexColumn gap="15px">
234
+ <FlexRow gap="10px">
235
+ <Button>Home</Button>
236
+ <Button expand>Current Page Title</Button>
237
+ <Button alignX="end">Profile</Button>
238
+ </FlexRow>
239
+
240
+ <FlexRow gap="10px" alignX="center">
241
+ <Button marginX="5px">Tab 1</Button>
242
+ <Button marginX="5px">Tab 2</Button>
243
+ <Button marginX="5px">Tab 3</Button>
244
+ </FlexRow>
245
+
246
+ <FlexRow gap="10px" alignX="space-between">
247
+ <Button>Previous</Button>
248
+ <Button>Next</Button>
249
+ </FlexRow>
250
+ </FlexColumn>
251
+ </div>
252
+ </div>
253
+ </div>
254
+ );
255
+ };
256
+
257
+ render(<Demo />, document.getElementById("app"));
258
+ </script>
259
+ </body>
260
+ </html>