@jsenv/navi 0.9.1 → 0.9.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.
@@ -22296,6 +22296,7 @@ const FormBasic = forwardRef((props, ref) => {
22296
22296
  const {
22297
22297
  readOnly,
22298
22298
  loading,
22299
+ style,
22299
22300
  children,
22300
22301
  ...rest
22301
22302
  } = props;
@@ -22312,9 +22313,14 @@ const FormBasic = forwardRef((props, ref) => {
22312
22313
  loading
22313
22314
  };
22314
22315
  }, [loading]);
22316
+ const {
22317
+ all
22318
+ } = useLayoutStyle(rest);
22319
+ const innerStyle = withPropsStyle(all, style);
22315
22320
  return jsx("form", {
22316
22321
  ...rest,
22317
22322
  ref: innerRef,
22323
+ style: innerStyle,
22318
22324
  onReset: e => {
22319
22325
  // browser would empty all fields to their default values (likely empty/unchecked)
22320
22326
  // we want to reset to the last known external state instead
@@ -22662,7 +22668,6 @@ const SelectControlled = forwardRef((props, ref) => {
22662
22668
  const selectElement = jsx("select", {
22663
22669
  className: "navi_select",
22664
22670
  ref: innerRef,
22665
- "data-field": "",
22666
22671
  "data-readonly": readOnly && !disabled ? "" : undefined,
22667
22672
  onKeyDown: e => {
22668
22673
  if (readOnly) {
@@ -24289,49 +24294,124 @@ const createSelectionKeyboardShortcuts = (selectionController, {
24289
24294
  }];
24290
24295
  };
24291
24296
 
24297
+ installImportMetaCss(import.meta);import.meta.css = /* css */`
24298
+ :root {
24299
+ --navi-icon-align-y: center;
24300
+ }
24301
+
24302
+ .navi_text {
24303
+ display: inline-flex;
24304
+ align-items: baseline;
24305
+ gap: 0.1em;
24306
+ }
24307
+
24308
+ .navi_icon {
24309
+ --align-y: var(--navi-icon-align-y, center);
24310
+
24311
+ display: inline-flex;
24312
+ width: 1em;
24313
+ height: 1em;
24314
+ flex-shrink: 0;
24315
+ align-self: var(--align-y);
24316
+ line-height: 1em;
24317
+ }
24318
+ `;
24319
+ const useTypographyStyle = props => {
24320
+ const color = props.color;
24321
+ const bold = props.bold;
24322
+ const italic = props.italic;
24323
+ const underline = props.underline;
24324
+ const size = props.size;
24325
+ delete props.color;
24326
+ delete props.bold;
24327
+ delete props.italic;
24328
+ delete props.underline;
24329
+ delete props.size;
24330
+ return {
24331
+ color,
24332
+ fontWeight: bold ? "bold" : bold === undefined ? undefined : "normal",
24333
+ fontStyle: italic ? "italic" : italic === undefined ? undefined : "normal",
24334
+ fontSize: size,
24335
+ textDecoration: underline ? "underline" : underline === undefined ? undefined : "none"
24336
+ };
24337
+ };
24338
+ const Text = ({
24339
+ style,
24340
+ children,
24341
+ ...rest
24342
+ }) => {
24343
+ const {
24344
+ all
24345
+ } = useLayoutStyle(rest);
24346
+ const innerStyle = withPropsStyle({
24347
+ ...all,
24348
+ ...useTypographyStyle(rest)
24349
+ }, style);
24350
+ return jsx("span", {
24351
+ ...rest,
24352
+ className: "navi_text",
24353
+ style: innerStyle,
24354
+ children: children
24355
+ });
24356
+ };
24357
+ const Icon = ({
24358
+ style,
24359
+ children,
24360
+ ...rest
24361
+ }) => {
24362
+ const {
24363
+ all
24364
+ } = useLayoutStyle(rest);
24365
+ const innerStyle = withPropsStyle({
24366
+ ...all,
24367
+ ...useTypographyStyle(rest)
24368
+ }, style);
24369
+ return jsx("span", {
24370
+ ...rest,
24371
+ className: "navi_icon",
24372
+ style: innerStyle,
24373
+ children: children
24374
+ });
24375
+ };
24376
+
24292
24377
  installImportMetaCss(import.meta);import.meta.css = /* css */`
24293
24378
  .navi_link {
24294
24379
  border-radius: 2px;
24295
24380
  }
24296
-
24381
+ /* Focus */
24297
24382
  .navi_link:focus {
24298
24383
  position: relative;
24299
24384
  z-index: 1; /* Ensure focus outline is above other elements */
24300
24385
  }
24301
-
24302
- .navi_link[data-readonly] > *,
24303
- .navi_link[inert] > * {
24304
- opacity: 0.5;
24305
- }
24306
-
24307
- .navi_link[inert] {
24308
- pointer-events: none;
24386
+ /* Visited */
24387
+ .navi_link[data-visited] {
24388
+ color: light-dark(#6a1b9a, #ab47bc);
24309
24389
  }
24310
-
24390
+ /* Selected */
24311
24391
  .navi_link[aria-selected] {
24312
24392
  position: relative;
24313
24393
  }
24314
-
24394
+ .navi_link[aria-selected="true"] {
24395
+ background-color: light-dark(#bbdefb, #2563eb);
24396
+ }
24315
24397
  .navi_link[aria-selected] input[type="checkbox"] {
24316
24398
  position: absolute;
24317
24399
  opacity: 0;
24318
24400
  }
24319
-
24320
- /* Visual feedback for selected state */
24321
- .navi_link[aria-selected="true"] {
24322
- background-color: light-dark(#bbdefb, #2563eb);
24323
- }
24324
-
24401
+ /* Active */
24325
24402
  .navi_link[data-active] {
24326
24403
  font-weight: bold;
24327
24404
  }
24328
-
24329
- .navi_link[data-visited] {
24330
- color: light-dark(#6a1b9a, #ab47bc);
24405
+ /* Readonly */
24406
+ .navi_link[data-readonly] > * {
24407
+ opacity: 0.5;
24331
24408
  }
24332
-
24333
- .navi_link[data-no-text-decoration] {
24334
- text-decoration: none;
24409
+ /* Disabled */
24410
+ .navi_link[inert] {
24411
+ pointer-events: none;
24412
+ }
24413
+ .navi_link[inert] > * {
24414
+ opacity: 0.5;
24335
24415
  }
24336
24416
  `;
24337
24417
  const Link = forwardRef((props, ref) => {
@@ -24383,7 +24463,10 @@ const LinkPlain = forwardRef((props, ref) => {
24383
24463
  const {
24384
24464
  all
24385
24465
  } = useLayoutStyle(rest);
24386
- const innerStyle = withPropsStyle(all, style);
24466
+ const innerStyle = withPropsStyle({
24467
+ ...all,
24468
+ ...useTypographyStyle(rest)
24469
+ }, style);
24387
24470
  return jsx(LoadableInlineElement, {
24388
24471
  loading: loading,
24389
24472
  color: "light-dark(#355fcc, #3b82f6)",
@@ -24395,7 +24478,7 @@ const LinkPlain = forwardRef((props, ref) => {
24395
24478
  style: innerStyle,
24396
24479
  "aria-busy": loading,
24397
24480
  inert: disabled,
24398
- "data-field": "",
24481
+ "data-disabled": disabled ? "" : undefined,
24399
24482
  "data-readonly": readOnly ? "" : undefined,
24400
24483
  "data-active": active ? "" : undefined,
24401
24484
  "data-visited": visited || isVisited ? "" : undefined,
@@ -28207,79 +28290,6 @@ const Overflow = ({
28207
28290
  });
28208
28291
  };
28209
28292
 
28210
- installImportMetaCss(import.meta);import.meta.css = /* css */`
28211
- :root {
28212
- --navi-icon-align-y: center;
28213
- }
28214
-
28215
- .navi_text {
28216
- display: inline-flex;
28217
- align-items: baseline;
28218
- gap: 0.1em;
28219
- }
28220
-
28221
- .navi_icon {
28222
- --align-y: var(--navi-icon-align-y, center);
28223
-
28224
- display: inline-flex;
28225
- width: 1em;
28226
- height: 1em;
28227
- flex-shrink: 0;
28228
- align-self: var(--align-y);
28229
- line-height: 1em;
28230
- }
28231
- `;
28232
- const Text = ({
28233
- children,
28234
- color,
28235
- bold,
28236
- italic,
28237
- underline,
28238
- style,
28239
- ...rest
28240
- }) => {
28241
- const {
28242
- all
28243
- } = useLayoutStyle(rest);
28244
- const innerStyle = withPropsStyle({
28245
- ...all,
28246
- color,
28247
- fontWeight: bold ? "bold" : undefined,
28248
- fontStyle: italic ? "italic" : undefined,
28249
- textDecoration: underline ? "underline" : undefined
28250
- }, style);
28251
- return jsx("span", {
28252
- ...rest,
28253
- className: "navi_text",
28254
- style: innerStyle,
28255
- children: children
28256
- });
28257
- };
28258
- const alignYMapping = {
28259
- start: "flex-start",
28260
- center: "center",
28261
- end: "flex-end"
28262
- };
28263
- const Icon = ({
28264
- alignY,
28265
- style,
28266
- children,
28267
- ...rest
28268
- }) => {
28269
- const innerStyle = {
28270
- ...style
28271
- };
28272
- if (alignY !== "center") {
28273
- innerStyle["--align-y"] = alignYMapping[alignY];
28274
- }
28275
- return jsx("span", {
28276
- ...rest,
28277
- className: "navi_icon",
28278
- style: innerStyle,
28279
- children: children
28280
- });
28281
- };
28282
-
28283
28293
  installImportMetaCss(import.meta);import.meta.css = /* css */`
28284
28294
  .text_and_count {
28285
28295
  display: flex;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/navi",
3
- "version": "0.9.1",
3
+ "version": "0.9.3",
4
4
  "description": "Library of components including navigation to create frontend applications",
5
5
  "repository": {
6
6
  "type": "git",
@@ -25,6 +25,8 @@ import {
25
25
  import { renderActionableComponent } from "../action_execution/render_actionable_component.jsx";
26
26
  import { useActionBoundToOneParam } from "../action_execution/use_action.js";
27
27
  import { useExecuteAction } from "../action_execution/use_execute_action.js";
28
+ import { useLayoutStyle } from "../layout/use_layout_style.js";
29
+ import { withPropsStyle } from "../props_composition/with_props_style.js";
28
30
  import { collectFormElementValues } from "./collect_form_element_values.js";
29
31
  import {
30
32
  useActionEvents,
@@ -75,7 +77,7 @@ export const Form = forwardRef((props, ref) => {
75
77
 
76
78
  const FormBasic = forwardRef((props, ref) => {
77
79
  const uiStateController = useContext(UIStateControllerContext);
78
- const { readOnly, loading, children, ...rest } = props;
80
+ const { readOnly, loading, style, children, ...rest } = props;
79
81
  const innerRef = useRef();
80
82
  useImperativeHandle(ref, () => innerRef.current);
81
83
 
@@ -90,10 +92,14 @@ const FormBasic = forwardRef((props, ref) => {
90
92
  return { loading };
91
93
  }, [loading]);
92
94
 
95
+ const { all } = useLayoutStyle(rest);
96
+ const innerStyle = withPropsStyle(all, style);
97
+
93
98
  return (
94
99
  <form
95
100
  {...rest}
96
101
  ref={innerRef}
102
+ style={innerStyle}
97
103
  onReset={(e) => {
98
104
  // browser would empty all fields to their default values (likely empty/unchecked)
99
105
  // we want to reset to the last known external state instead
@@ -37,7 +37,6 @@ const SelectControlled = forwardRef((props, ref) => {
37
37
  <select
38
38
  className="navi_select"
39
39
  ref={innerRef}
40
- data-field=""
41
40
  data-readonly={readOnly && !disabled ? "" : undefined}
42
41
  onKeyDown={(e) => {
43
42
  if (readOnly) {
@@ -20,6 +20,7 @@ import {
20
20
  SelectionContext,
21
21
  useSelectableElement,
22
22
  } from "../selection/selection.jsx";
23
+ import { useTypographyStyle } from "../text/text.jsx";
23
24
  import { useAutoFocus } from "../use_auto_focus.js";
24
25
 
25
26
  /*
@@ -35,45 +36,40 @@ import.meta.css = /* css */ `
35
36
  .navi_link {
36
37
  border-radius: 2px;
37
38
  }
38
-
39
+ /* Focus */
39
40
  .navi_link:focus {
40
41
  position: relative;
41
42
  z-index: 1; /* Ensure focus outline is above other elements */
42
43
  }
43
-
44
- .navi_link[data-readonly] > *,
45
- .navi_link[inert] > * {
46
- opacity: 0.5;
47
- }
48
-
49
- .navi_link[inert] {
50
- pointer-events: none;
44
+ /* Visited */
45
+ .navi_link[data-visited] {
46
+ color: light-dark(#6a1b9a, #ab47bc);
51
47
  }
52
-
48
+ /* Selected */
53
49
  .navi_link[aria-selected] {
54
50
  position: relative;
55
51
  }
56
-
52
+ .navi_link[aria-selected="true"] {
53
+ background-color: light-dark(#bbdefb, #2563eb);
54
+ }
57
55
  .navi_link[aria-selected] input[type="checkbox"] {
58
56
  position: absolute;
59
57
  opacity: 0;
60
58
  }
61
-
62
- /* Visual feedback for selected state */
63
- .navi_link[aria-selected="true"] {
64
- background-color: light-dark(#bbdefb, #2563eb);
65
- }
66
-
59
+ /* Active */
67
60
  .navi_link[data-active] {
68
61
  font-weight: bold;
69
62
  }
70
-
71
- .navi_link[data-visited] {
72
- color: light-dark(#6a1b9a, #ab47bc);
63
+ /* Readonly */
64
+ .navi_link[data-readonly] > * {
65
+ opacity: 0.5;
73
66
  }
74
-
75
- .navi_link[data-no-text-decoration] {
76
- text-decoration: none;
67
+ /* Disabled */
68
+ .navi_link[inert] {
69
+ pointer-events: none;
70
+ }
71
+ .navi_link[inert] > * {
72
+ opacity: 0.5;
77
73
  }
78
74
  `;
79
75
 
@@ -122,7 +118,13 @@ const LinkPlain = forwardRef((props, ref) => {
122
118
 
123
119
  const innerClassName = withPropsClassName("navi_link", className);
124
120
  const { all } = useLayoutStyle(rest);
125
- const innerStyle = withPropsStyle(all, style);
121
+ const innerStyle = withPropsStyle(
122
+ {
123
+ ...all,
124
+ ...useTypographyStyle(rest),
125
+ },
126
+ style,
127
+ );
126
128
 
127
129
  return (
128
130
  <LoadableInlineElement
@@ -137,7 +139,7 @@ const LinkPlain = forwardRef((props, ref) => {
137
139
  style={innerStyle}
138
140
  aria-busy={loading}
139
141
  inert={disabled}
140
- data-field=""
142
+ data-disabled={disabled ? "" : undefined}
141
143
  data-readonly={readOnly ? "" : undefined}
142
144
  data-active={active ? "" : undefined}
143
145
  data-visited={visited || isVisited ? "" : undefined}
@@ -24,23 +24,36 @@ import.meta.css = /* css */ `
24
24
  }
25
25
  `;
26
26
 
27
- export const Text = ({
28
- children,
29
- color,
30
- bold,
31
- italic,
32
- underline,
33
- style,
34
- ...rest
35
- }) => {
27
+ export const useTypographyStyle = (props) => {
28
+ const color = props.color;
29
+ const bold = props.bold;
30
+ const italic = props.italic;
31
+ const underline = props.underline;
32
+ const size = props.size;
33
+ delete props.color;
34
+ delete props.bold;
35
+ delete props.italic;
36
+ delete props.underline;
37
+ delete props.size;
38
+ return {
39
+ color,
40
+ fontWeight: bold ? "bold" : bold === undefined ? undefined : "normal",
41
+ fontStyle: italic ? "italic" : italic === undefined ? undefined : "normal",
42
+ fontSize: size,
43
+ textDecoration: underline
44
+ ? "underline"
45
+ : underline === undefined
46
+ ? undefined
47
+ : "none",
48
+ };
49
+ };
50
+
51
+ export const Text = ({ style, children, ...rest }) => {
36
52
  const { all } = useLayoutStyle(rest);
37
53
  const innerStyle = withPropsStyle(
38
54
  {
39
55
  ...all,
40
- color,
41
- fontWeight: bold ? "bold" : undefined,
42
- fontStyle: italic ? "italic" : undefined,
43
- textDecoration: underline ? "underline" : undefined,
56
+ ...useTypographyStyle(rest),
44
57
  },
45
58
  style,
46
59
  );
@@ -52,16 +65,15 @@ export const Text = ({
52
65
  );
53
66
  };
54
67
 
55
- const alignYMapping = {
56
- start: "flex-start",
57
- center: "center",
58
- end: "flex-end",
59
- };
60
- export const Icon = ({ alignY, style, children, ...rest }) => {
61
- const innerStyle = { ...style };
62
- if (alignY !== "center") {
63
- innerStyle["--align-y"] = alignYMapping[alignY];
64
- }
68
+ export const Icon = ({ style, children, ...rest }) => {
69
+ const { all } = useLayoutStyle(rest);
70
+ const innerStyle = withPropsStyle(
71
+ {
72
+ ...all,
73
+ ...useTypographyStyle(rest),
74
+ },
75
+ style,
76
+ );
65
77
 
66
78
  return (
67
79
  <span {...rest} className="navi_icon" style={innerStyle}>