basefn 1.1.6 → 1.2.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": "basefn",
3
- "version": "1.1.6",
3
+ "version": "1.2.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/brnrdog/basefn.git"
package/src/Basefn.res CHANGED
@@ -41,6 +41,7 @@ type sidebarNavSection = Basefn__Sidebar.navSection
41
41
  type topbarSize = Basefn__Topbar.size
42
42
  type topbarNavItem = Basefn__Topbar.navItem
43
43
  type appLayoutContentWidth = Basefn__AppLayout.contentWidth
44
+ type appLayoutTopbarPosition = Basefn__AppLayout.topbarPosition
44
45
  type iconName = Basefn__Icon.name
45
46
  type iconSize = Basefn__Icon.size
46
47
  type gridColumns = Basefn__Grid.columns
@@ -4,6 +4,23 @@
4
4
  width: 100%;
5
5
  }
6
6
 
7
+ .basefn-app-layout__body {
8
+ display: flex;
9
+ flex: 1;
10
+ min-height: 100vh;
11
+ width: 100%;
12
+ }
13
+
14
+ /* When topbar is above, adjust layout direction */
15
+ .basefn-app-layout--topbar-above {
16
+ flex-direction: column;
17
+ }
18
+
19
+ .basefn-app-layout--topbar-above .basefn-app-layout__body {
20
+ flex: 1;
21
+ min-height: 0;
22
+ }
23
+
7
24
  .basefn-app-layout__sidebar {
8
25
  position: fixed;
9
26
  left: 0;
@@ -12,6 +29,19 @@
12
29
  z-index: 200;
13
30
  }
14
31
 
32
+ /* When topbar is above, sidebar starts below topbar */
33
+ .basefn-app-layout--topbar-above .basefn-app-layout__sidebar {
34
+ top: 64px; /* Default topbar height (md) */
35
+ }
36
+
37
+ .basefn-app-layout--topbar-above.basefn-app-layout--topbar-sm .basefn-app-layout__sidebar {
38
+ top: 56px;
39
+ }
40
+
41
+ .basefn-app-layout--topbar-above.basefn-app-layout--topbar-lg .basefn-app-layout__sidebar {
42
+ top: 72px;
43
+ }
44
+
15
45
  .basefn-app-layout__main-wrapper {
16
46
  flex: 1;
17
47
  display: flex;
@@ -43,6 +73,14 @@
43
73
  z-index: 100;
44
74
  }
45
75
 
76
+ /* When topbar is above all content */
77
+ .basefn-app-layout__topbar--above {
78
+ position: sticky;
79
+ top: 0;
80
+ width: 100%;
81
+ z-index: 201; /* Above sidebar */
82
+ }
83
+
46
84
  .basefn-app-layout__content {
47
85
  flex: 1;
48
86
  display: flex;
@@ -97,4 +135,17 @@
97
135
  .basefn-app-layout--sidebar-open .basefn-app-layout__sidebar-backdrop {
98
136
  display: block;
99
137
  }
138
+
139
+ /* When topbar is above, adjust sidebar and backdrop position */
140
+ .basefn-app-layout--topbar-above .basefn-app-layout__sidebar-backdrop {
141
+ top: 64px; /* Start below topbar (md) */
142
+ }
143
+
144
+ .basefn-app-layout--topbar-above.basefn-app-layout--topbar-sm .basefn-app-layout__sidebar-backdrop {
145
+ top: 56px;
146
+ }
147
+
148
+ .basefn-app-layout--topbar-above.basefn-app-layout--topbar-lg .basefn-app-layout__sidebar-backdrop {
149
+ top: 72px;
150
+ }
100
151
  }
@@ -3,6 +3,7 @@
3
3
  open Xote
4
4
 
5
5
  type contentWidth = FullWidth | Contained
6
+ type topbarPosition = Inline | AboveAll
6
7
 
7
8
  @jsx.component
8
9
  let make = (
@@ -13,6 +14,8 @@ let make = (
13
14
  ~noPadding: bool=false,
14
15
  ~sidebarSize: option<string>=?, // "sm" | "md" | "lg"
15
16
  ~sidebarCollapsed: bool=false,
17
+ ~topbarPosition: topbarPosition=Inline,
18
+ ~topbarSize: option<string>=?, // "sm" | "md" | "lg"
16
19
  ) => {
17
20
  let sidebarOpen = Signal.make(false)
18
21
 
@@ -24,10 +27,24 @@ let make = (
24
27
  | _ => ""
25
28
  }
26
29
  let collapsedClass = sidebarCollapsed ? " basefn-app-layout--sidebar-collapsed" : ""
30
+ let topbarPositionClass = switch topbarPosition {
31
+ | AboveAll => " basefn-app-layout--topbar-above"
32
+ | Inline => ""
33
+ }
34
+ let topbarSizeClass = switch (topbarPosition, topbarSize) {
35
+ | (AboveAll, Some("sm")) => " basefn-app-layout--topbar-sm"
36
+ | (AboveAll, Some("lg")) => " basefn-app-layout--topbar-lg"
37
+ | _ => ""
38
+ }
27
39
  let sidebarOpenClass = Computed.make(() =>
28
40
  Signal.get(sidebarOpen) ? " basefn-app-layout--sidebar-open" : ""
29
41
  )
30
- "basefn-app-layout" ++ hasSidebar ++ sidebarSizeClass ++ collapsedClass
42
+ "basefn-app-layout" ++
43
+ hasSidebar ++
44
+ sidebarSizeClass ++
45
+ collapsedClass ++
46
+ topbarPositionClass ++
47
+ topbarSizeClass
31
48
  }
32
49
 
33
50
  let getContentClass = () => {
@@ -51,24 +68,35 @@ let make = (
51
68
  )
52
69
  })}
53
70
  >
54
- {switch sidebar {
55
- | Some(sidebarContent) =>
56
- <>
57
- <div class="basefn-app-layout__sidebar"> {sidebarContent} </div>
58
- <div
59
- class="basefn-app-layout__sidebar-backdrop" onClick={_ => Signal.set(sidebarOpen, false)}
60
- />
61
- </>
62
- | None => <> </>
71
+ {switch (topbarPosition, topbar) {
72
+ | (AboveAll, Some(topbarContent)) =>
73
+ <div class="basefn-app-layout__topbar basefn-app-layout__topbar--above">
74
+ {topbarContent}
75
+ </div>
76
+ | _ => <> </>
63
77
  }}
64
- <div class="basefn-app-layout__main-wrapper">
65
- {switch topbar {
66
- | Some(topbarContent) => <div class="basefn-app-layout__topbar"> {topbarContent} </div>
78
+ <div class="basefn-app-layout__body">
79
+ {switch sidebar {
80
+ | Some(sidebarContent) =>
81
+ <>
82
+ <div class="basefn-app-layout__sidebar"> {sidebarContent} </div>
83
+ <div
84
+ class="basefn-app-layout__sidebar-backdrop"
85
+ onClick={_ => Signal.set(sidebarOpen, false)}
86
+ />
87
+ </>
67
88
  | None => <> </>
68
89
  }}
69
- <main class="basefn-app-layout__content">
70
- <div class={getContentClass()}> {children} </div>
71
- </main>
90
+ <div class="basefn-app-layout__main-wrapper">
91
+ {switch (topbarPosition, topbar) {
92
+ | (Inline, Some(topbarContent)) =>
93
+ <div class="basefn-app-layout__topbar"> {topbarContent} </div>
94
+ | _ => <> </>
95
+ }}
96
+ <main class="basefn-app-layout__content">
97
+ <div class={getContentClass()}> {children} </div>
98
+ </main>
99
+ </div>
72
100
  </div>
73
101
  </div>
74
102
  }
@@ -8,6 +8,8 @@ import './Basefn__AppLayout.css'
8
8
  ;
9
9
 
10
10
  function Basefn__AppLayout(props) {
11
+ let topbarSize = props.topbarSize;
12
+ let __topbarPosition = props.topbarPosition;
11
13
  let __sidebarCollapsed = props.sidebarCollapsed;
12
14
  let sidebarSize = props.sidebarSize;
13
15
  let __noPadding = props.noPadding;
@@ -17,6 +19,7 @@ function Basefn__AppLayout(props) {
17
19
  let contentWidth = __contentWidth !== undefined ? __contentWidth : "FullWidth";
18
20
  let noPadding = __noPadding !== undefined ? __noPadding : false;
19
21
  let sidebarCollapsed = __sidebarCollapsed !== undefined ? __sidebarCollapsed : false;
22
+ let topbarPosition = __topbarPosition !== undefined ? __topbarPosition : "Inline";
20
23
  let sidebarOpen = Xote.Signal.make(false, undefined, undefined);
21
24
  let getLayoutClass = () => {
22
25
  let hasSidebar = Core__Option.isSome(sidebar) ? " basefn-app-layout--has-sidebar" : "";
@@ -36,6 +39,23 @@ function Basefn__AppLayout(props) {
36
39
  sidebarSizeClass = "";
37
40
  }
38
41
  let collapsedClass = sidebarCollapsed ? " basefn-app-layout--sidebar-collapsed" : "";
42
+ let topbarPositionClass;
43
+ topbarPositionClass = topbarPosition === "Inline" ? "" : " basefn-app-layout--topbar-above";
44
+ let topbarSizeClass;
45
+ if (topbarPosition === "Inline" || topbarSize === undefined) {
46
+ topbarSizeClass = "";
47
+ } else {
48
+ switch (topbarSize) {
49
+ case "lg" :
50
+ topbarSizeClass = " basefn-app-layout--topbar-lg";
51
+ break;
52
+ case "sm" :
53
+ topbarSizeClass = " basefn-app-layout--topbar-sm";
54
+ break;
55
+ default:
56
+ topbarSizeClass = "";
57
+ }
58
+ }
39
59
  Xote.Computed.make(() => {
40
60
  if (Xote.Signal.get(sidebarOpen)) {
41
61
  return " basefn-app-layout--sidebar-open";
@@ -43,7 +63,7 @@ function Basefn__AppLayout(props) {
43
63
  return "";
44
64
  }
45
65
  }, undefined);
46
- return "basefn-app-layout" + hasSidebar + sidebarSizeClass + collapsedClass;
66
+ return "basefn-app-layout" + hasSidebar + sidebarSizeClass + collapsedClass + topbarPositionClass + topbarSizeClass;
47
67
  };
48
68
  let getContentClass = () => {
49
69
  let widthClass;
@@ -51,6 +71,16 @@ function Basefn__AppLayout(props) {
51
71
  let paddingClass = noPadding ? " basefn-app-layout__content-inner--no-padding" : "";
52
72
  return "basefn-app-layout__content-inner" + widthClass + paddingClass;
53
73
  };
74
+ let tmp;
75
+ tmp = topbarPosition === "Inline" || topbar === undefined ? Xote__JSX.jsx(Xote__JSX.jsxFragment, {}) : Xote__JSX.Elements.jsx("div", {
76
+ class: "basefn-app-layout__topbar basefn-app-layout__topbar--above",
77
+ children: topbar
78
+ });
79
+ let tmp$1;
80
+ tmp$1 = topbarPosition === "Inline" && topbar !== undefined ? Xote__JSX.Elements.jsx("div", {
81
+ class: "basefn-app-layout__topbar",
82
+ children: topbar
83
+ }) : Xote__JSX.jsx(Xote__JSX.jsxFragment, {});
54
84
  return Xote__JSX.Elements.jsxs("div", {
55
85
  class: Xote.Computed.make(() => getLayoutClass() + Xote.Signal.get(Xote.Computed.make(() => {
56
86
  if (Xote.Signal.get(sidebarOpen)) {
@@ -60,31 +90,34 @@ function Basefn__AppLayout(props) {
60
90
  }
61
91
  }, undefined)), undefined),
62
92
  children: Xote__JSX.array([
63
- sidebar !== undefined ? Xote__JSX.jsxs(Xote__JSX.jsxFragment, {
64
- children: Xote__JSX.array([
65
- Xote__JSX.Elements.jsx("div", {
66
- class: "basefn-app-layout__sidebar",
67
- children: sidebar
68
- }),
69
- Xote__JSX.Elements.jsx("div", {
70
- class: "basefn-app-layout__sidebar-backdrop",
71
- onClick: param => Xote.Signal.set(sidebarOpen, false)
72
- })
73
- ])
74
- }) : Xote__JSX.jsx(Xote__JSX.jsxFragment, {}),
93
+ tmp,
75
94
  Xote__JSX.Elements.jsxs("div", {
76
- class: "basefn-app-layout__main-wrapper",
95
+ class: "basefn-app-layout__body",
77
96
  children: Xote__JSX.array([
78
- topbar !== undefined ? Xote__JSX.Elements.jsx("div", {
79
- class: "basefn-app-layout__topbar",
80
- children: topbar
97
+ sidebar !== undefined ? Xote__JSX.jsxs(Xote__JSX.jsxFragment, {
98
+ children: Xote__JSX.array([
99
+ Xote__JSX.Elements.jsx("div", {
100
+ class: "basefn-app-layout__sidebar",
101
+ children: sidebar
102
+ }),
103
+ Xote__JSX.Elements.jsx("div", {
104
+ class: "basefn-app-layout__sidebar-backdrop",
105
+ onClick: param => Xote.Signal.set(sidebarOpen, false)
106
+ })
107
+ ])
81
108
  }) : Xote__JSX.jsx(Xote__JSX.jsxFragment, {}),
82
- Xote__JSX.Elements.jsx("main", {
83
- class: "basefn-app-layout__content",
84
- children: Xote__JSX.Elements.jsx("div", {
85
- class: getContentClass(),
86
- children: props.children
87
- })
109
+ Xote__JSX.Elements.jsxs("div", {
110
+ class: "basefn-app-layout__main-wrapper",
111
+ children: Xote__JSX.array([
112
+ tmp$1,
113
+ Xote__JSX.Elements.jsx("main", {
114
+ class: "basefn-app-layout__content",
115
+ children: Xote__JSX.Elements.jsx("div", {
116
+ class: getContentClass(),
117
+ children: props.children
118
+ })
119
+ })
120
+ ])
88
121
  })
89
122
  ])
90
123
  })