basefn 1.0.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.
Files changed (154) hide show
  1. package/README.md +104 -0
  2. package/package.json +82 -0
  3. package/rescript.json +32 -0
  4. package/src/Basefn.css +14 -0
  5. package/src/Basefn.res +105 -0
  6. package/src/Basefn.res.mjs +114 -0
  7. package/src/Basefn__Dom.res +9 -0
  8. package/src/Basefn__Dom.res.mjs +24 -0
  9. package/src/Basefn__Utils.res +15 -0
  10. package/src/Basefn__Utils.res.mjs +32 -0
  11. package/src/Demo.res +1417 -0
  12. package/src/Demo.res.mjs +2328 -0
  13. package/src/Eita.res.mjs +105 -0
  14. package/src/Eita__Accordion.res.mjs +77 -0
  15. package/src/Eita__Alert.res.mjs +81 -0
  16. package/src/Eita__AppLayout.res.mjs +100 -0
  17. package/src/Eita__Avatar.res.mjs +40 -0
  18. package/src/Eita__Badge.res.mjs +65 -0
  19. package/src/Eita__Breadcrumb.res.mjs +53 -0
  20. package/src/Eita__Button.res.mjs +47 -0
  21. package/src/Eita__Card.res.mjs +60 -0
  22. package/src/Eita__Checkbox.res.mjs +36 -0
  23. package/src/Eita__Dom.res.mjs +16 -0
  24. package/src/Eita__Drawer.res.mjs +112 -0
  25. package/src/Eita__Dropdown.res.mjs +96 -0
  26. package/src/Eita__Grid.res.mjs +24 -0
  27. package/src/Eita__Input.res.mjs +54 -0
  28. package/src/Eita__Kbd.res.mjs +42 -0
  29. package/src/Eita__Label.res.mjs +24 -0
  30. package/src/Eita__Modal.res.mjs +93 -0
  31. package/src/Eita__Progress.res.mjs +101 -0
  32. package/src/Eita__Radio.res.mjs +38 -0
  33. package/src/Eita__Select.res.mjs +40 -0
  34. package/src/Eita__Separator.res.mjs +70 -0
  35. package/src/Eita__Sidebar.res.mjs +103 -0
  36. package/src/Eita__Slider.res.mjs +89 -0
  37. package/src/Eita__Spinner.res.mjs +69 -0
  38. package/src/Eita__Stepper.res.mjs +114 -0
  39. package/src/Eita__Switch.res.mjs +84 -0
  40. package/src/Eita__Tabs.res.mjs +57 -0
  41. package/src/Eita__Textarea.res.mjs +39 -0
  42. package/src/Eita__Timeline.res.mjs +86 -0
  43. package/src/Eita__Toast.res.mjs +112 -0
  44. package/src/Eita__Tooltip.res.mjs +60 -0
  45. package/src/Eita__Topbar.res.mjs +96 -0
  46. package/src/Eita__Typography.res.mjs +183 -0
  47. package/src/Eita__Utils.res.mjs +32 -0
  48. package/src/Example.res +111 -0
  49. package/src/Example.res.mjs +176 -0
  50. package/src/components/Basefn__Accordion.css +70 -0
  51. package/src/components/Basefn__Accordion.res +79 -0
  52. package/src/components/Basefn__Accordion.res.mjs +77 -0
  53. package/src/components/Basefn__Alert.css +79 -0
  54. package/src/components/Basefn__Alert.res +68 -0
  55. package/src/components/Basefn__Alert.res.mjs +78 -0
  56. package/src/components/Basefn__AppLayout.css +100 -0
  57. package/src/components/Basefn__AppLayout.res +74 -0
  58. package/src/components/Basefn__AppLayout.res.mjs +100 -0
  59. package/src/components/Basefn__Avatar.css +25 -0
  60. package/src/components/Basefn__Avatar.res +23 -0
  61. package/src/components/Basefn__Avatar.res.mjs +40 -0
  62. package/src/components/Basefn__Badge.css +71 -0
  63. package/src/components/Basefn__Badge.res +43 -0
  64. package/src/components/Basefn__Badge.res.mjs +65 -0
  65. package/src/components/Basefn__Breadcrumb.css +36 -0
  66. package/src/components/Basefn__Breadcrumb.res +45 -0
  67. package/src/components/Basefn__Breadcrumb.res.mjs +53 -0
  68. package/src/components/Basefn__Button.css +83 -0
  69. package/src/components/Basefn__Button.res +32 -0
  70. package/src/components/Basefn__Button.res.mjs +54 -0
  71. package/src/components/Basefn__Card.css +50 -0
  72. package/src/components/Basefn__Card.res +45 -0
  73. package/src/components/Basefn__Card.res.mjs +60 -0
  74. package/src/components/Basefn__Checkbox.css +72 -0
  75. package/src/components/Basefn__Checkbox.res +25 -0
  76. package/src/components/Basefn__Checkbox.res.mjs +36 -0
  77. package/src/components/Basefn__Drawer.css +168 -0
  78. package/src/components/Basefn__Drawer.res +86 -0
  79. package/src/components/Basefn__Drawer.res.mjs +112 -0
  80. package/src/components/Basefn__Dropdown.css +76 -0
  81. package/src/components/Basefn__Dropdown.res +85 -0
  82. package/src/components/Basefn__Dropdown.res.mjs +96 -0
  83. package/src/components/Basefn__Grid.css +11 -0
  84. package/src/components/Basefn__Grid.res +296 -0
  85. package/src/components/Basefn__Grid.res.mjs +263 -0
  86. package/src/components/Basefn__Icon.css +12 -0
  87. package/src/components/Basefn__Icon.res +196 -0
  88. package/src/components/Basefn__Icon.res.mjs +183 -0
  89. package/src/components/Basefn__Input.css +44 -0
  90. package/src/components/Basefn__Input.res +48 -0
  91. package/src/components/Basefn__Input.res.mjs +63 -0
  92. package/src/components/Basefn__Kbd.css +65 -0
  93. package/src/components/Basefn__Kbd.res +27 -0
  94. package/src/components/Basefn__Kbd.res.mjs +42 -0
  95. package/src/components/Basefn__Label.css +22 -0
  96. package/src/components/Basefn__Label.res +18 -0
  97. package/src/components/Basefn__Label.res.mjs +24 -0
  98. package/src/components/Basefn__Modal.css +100 -0
  99. package/src/components/Basefn__Modal.res +74 -0
  100. package/src/components/Basefn__Modal.res.mjs +93 -0
  101. package/src/components/Basefn__Progress.css +69 -0
  102. package/src/components/Basefn__Progress.res +88 -0
  103. package/src/components/Basefn__Progress.res.mjs +101 -0
  104. package/src/components/Basefn__Radio.css +72 -0
  105. package/src/components/Basefn__Radio.res +35 -0
  106. package/src/components/Basefn__Radio.res.mjs +38 -0
  107. package/src/components/Basefn__Select.css +44 -0
  108. package/src/components/Basefn__Select.res +33 -0
  109. package/src/components/Basefn__Select.res.mjs +40 -0
  110. package/src/components/Basefn__Separator.css +85 -0
  111. package/src/components/Basefn__Separator.res +45 -0
  112. package/src/components/Basefn__Separator.res.mjs +70 -0
  113. package/src/components/Basefn__Sidebar.css +141 -0
  114. package/src/components/Basefn__Sidebar.res +95 -0
  115. package/src/components/Basefn__Sidebar.res.mjs +107 -0
  116. package/src/components/Basefn__Slider.css +97 -0
  117. package/src/components/Basefn__Slider.res +68 -0
  118. package/src/components/Basefn__Slider.res.mjs +89 -0
  119. package/src/components/Basefn__Spinner.css +63 -0
  120. package/src/components/Basefn__Spinner.res +44 -0
  121. package/src/components/Basefn__Spinner.res.mjs +69 -0
  122. package/src/components/Basefn__Stepper.css +141 -0
  123. package/src/components/Basefn__Stepper.res +86 -0
  124. package/src/components/Basefn__Stepper.res.mjs +114 -0
  125. package/src/components/Basefn__Switch.css +80 -0
  126. package/src/components/Basefn__Switch.res +62 -0
  127. package/src/components/Basefn__Switch.res.mjs +84 -0
  128. package/src/components/Basefn__Tabs.css +54 -0
  129. package/src/components/Basefn__Tabs.res +73 -0
  130. package/src/components/Basefn__Tabs.res.mjs +57 -0
  131. package/src/components/Basefn__Textarea.css +41 -0
  132. package/src/components/Basefn__Textarea.res +28 -0
  133. package/src/components/Basefn__Textarea.res.mjs +41 -0
  134. package/src/components/Basefn__ThemeToggle.css +5 -0
  135. package/src/components/Basefn__ThemeToggle.res +29 -0
  136. package/src/components/Basefn__ThemeToggle.res.mjs +49 -0
  137. package/src/components/Basefn__Timeline.css +144 -0
  138. package/src/components/Basefn__Timeline.res +70 -0
  139. package/src/components/Basefn__Timeline.res.mjs +86 -0
  140. package/src/components/Basefn__Toast.css +100 -0
  141. package/src/components/Basefn__Toast.res +92 -0
  142. package/src/components/Basefn__Toast.res.mjs +112 -0
  143. package/src/components/Basefn__Tooltip.css +84 -0
  144. package/src/components/Basefn__Tooltip.res +42 -0
  145. package/src/components/Basefn__Tooltip.res.mjs +60 -0
  146. package/src/components/Basefn__Topbar.css +130 -0
  147. package/src/components/Basefn__Topbar.res +92 -0
  148. package/src/components/Basefn__Topbar.res.mjs +91 -0
  149. package/src/components/Basefn__Typography.css +120 -0
  150. package/src/components/Basefn__Typography.res +96 -0
  151. package/src/components/Basefn__Typography.res.mjs +175 -0
  152. package/src/styles/Basefn__Theme.res +63 -0
  153. package/src/styles/Basefn__Theme.res.mjs +65 -0
  154. package/src/styles/variables.css +199 -0
@@ -0,0 +1,100 @@
1
+ .basefn-app-layout {
2
+ display: flex;
3
+ min-height: 100vh;
4
+ width: 100%;
5
+ }
6
+
7
+ .basefn-app-layout__sidebar {
8
+ position: fixed;
9
+ left: 0;
10
+ top: 0;
11
+ bottom: 0;
12
+ z-index: 200;
13
+ }
14
+
15
+ .basefn-app-layout__main-wrapper {
16
+ flex: 1;
17
+ display: flex;
18
+ flex-direction: column;
19
+ min-height: 100vh;
20
+ }
21
+
22
+ /* When sidebar is present, push main content */
23
+ .basefn-app-layout--has-sidebar .basefn-app-layout__main-wrapper {
24
+ margin-left: 256px; /* Default sidebar width (md) */
25
+ }
26
+
27
+ .basefn-app-layout--sidebar-sm .basefn-app-layout__main-wrapper {
28
+ margin-left: 200px;
29
+ }
30
+
31
+ .basefn-app-layout--sidebar-lg .basefn-app-layout__main-wrapper {
32
+ margin-left: 320px;
33
+ }
34
+
35
+ .basefn-app-layout--sidebar-collapsed .basefn-app-layout__main-wrapper {
36
+ margin-left: 64px;
37
+ margin-left: 0;
38
+ }
39
+
40
+ .basefn-app-layout__topbar {
41
+ position: sticky;
42
+ top: 0;
43
+ z-index: 100;
44
+ }
45
+
46
+ .basefn-app-layout__content {
47
+ flex: 1;
48
+ display: flex;
49
+ flex-direction: column;
50
+ }
51
+
52
+ .basefn-app-layout__content-inner {
53
+ flex: 1;
54
+ padding: 1rem 2rem;
55
+ background-color: var(--basefn-bg-secondary);
56
+ }
57
+
58
+ .basefn-app-layout__content-inner--no-padding {
59
+ padding: 0;
60
+ }
61
+
62
+ /* Full width variant */
63
+ .basefn-app-layout--full-width .basefn-app-layout__content-inner {
64
+ max-width: none;
65
+ }
66
+
67
+ /* Contained variant */
68
+ .basefn-app-layout--contained .basefn-app-layout__content-inner {
69
+ max-width: 1280px;
70
+ margin: 0 auto;
71
+ width: 100%;
72
+ }
73
+
74
+ /* Mobile responsiveness */
75
+ @media (max-width: 768px) {
76
+ .basefn-app-layout__sidebar {
77
+ transform: translateX(-100%);
78
+ transition: transform 0.3s ease-out;
79
+ }
80
+
81
+ .basefn-app-layout--sidebar-open .basefn-app-layout__sidebar {
82
+ transform: translateX(0);
83
+ }
84
+
85
+ .basefn-app-layout--has-sidebar .basefn-app-layout__main-wrapper {
86
+ margin-left: 0;
87
+ }
88
+
89
+ .basefn-app-layout__sidebar-backdrop {
90
+ display: none;
91
+ position: fixed;
92
+ inset: 0;
93
+ background-color: var(--basefn-surface-overlay);
94
+ z-index: 199;
95
+ }
96
+
97
+ .basefn-app-layout--sidebar-open .basefn-app-layout__sidebar-backdrop {
98
+ display: block;
99
+ }
100
+ }
@@ -0,0 +1,74 @@
1
+ %%raw(`import './Basefn__AppLayout.css'`)
2
+
3
+ open Xote
4
+
5
+ type contentWidth = FullWidth | Contained
6
+
7
+ @jsx.component
8
+ let make = (
9
+ ~sidebar: option<Component.node>=?,
10
+ ~topbar: option<Component.node>=?,
11
+ ~children: Component.node,
12
+ ~contentWidth: contentWidth=FullWidth,
13
+ ~noPadding: bool=false,
14
+ ~sidebarSize: option<string>=?, // "sm" | "md" | "lg"
15
+ ~sidebarCollapsed: bool=false,
16
+ ) => {
17
+ let sidebarOpen = Signal.make(false)
18
+
19
+ let getLayoutClass = () => {
20
+ let hasSidebar = sidebar->Option.isSome ? " basefn-app-layout--has-sidebar" : ""
21
+ let sidebarSizeClass = switch sidebarSize {
22
+ | Some("sm") => " basefn-app-layout--sidebar-sm"
23
+ | Some("lg") => " basefn-app-layout--sidebar-lg"
24
+ | _ => ""
25
+ }
26
+ let collapsedClass = sidebarCollapsed ? " basefn-app-layout--sidebar-collapsed" : ""
27
+ let sidebarOpenClass = Computed.make(() =>
28
+ Signal.get(sidebarOpen) ? " basefn-app-layout--sidebar-open" : ""
29
+ )
30
+ "basefn-app-layout" ++ hasSidebar ++ sidebarSizeClass ++ collapsedClass
31
+ }
32
+
33
+ let getContentClass = () => {
34
+ let widthClass = switch contentWidth {
35
+ | FullWidth => " basefn-app-layout--full-width"
36
+ | Contained => " basefn-app-layout--contained"
37
+ }
38
+ let paddingClass = noPadding ? " basefn-app-layout__content-inner--no-padding" : ""
39
+ "basefn-app-layout__content-inner" ++ widthClass ++ paddingClass
40
+ }
41
+
42
+ let handleSidebarToggle = () => {
43
+ Signal.update(sidebarOpen, prev => !prev)
44
+ }
45
+
46
+ <div
47
+ class={Computed.make(() => {
48
+ getLayoutClass() ++
49
+ Signal.get(
50
+ Computed.make(() => Signal.get(sidebarOpen) ? " basefn-app-layout--sidebar-open" : ""),
51
+ )
52
+ })}
53
+ >
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 => <> </>
63
+ }}
64
+ <div class="basefn-app-layout__main-wrapper">
65
+ {switch topbar {
66
+ | Some(topbarContent) => <div class="basefn-app-layout__topbar"> {topbarContent} </div>
67
+ | None => <> </>
68
+ }}
69
+ <main class="basefn-app-layout__content">
70
+ <div class={getContentClass()}> {children} </div>
71
+ </main>
72
+ </div>
73
+ </div>
74
+ }
@@ -0,0 +1,100 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Xote from "xote/src/Xote.res.mjs";
4
+ import * as Xote__JSX from "xote/src/Xote__JSX.res.mjs";
5
+ import * as Core__Option from "@rescript/core/src/Core__Option.res.mjs";
6
+
7
+ import './Basefn__AppLayout.css'
8
+ ;
9
+
10
+ function Basefn__AppLayout(props) {
11
+ let __sidebarCollapsed = props.sidebarCollapsed;
12
+ let sidebarSize = props.sidebarSize;
13
+ let __noPadding = props.noPadding;
14
+ let __contentWidth = props.contentWidth;
15
+ let topbar = props.topbar;
16
+ let sidebar = props.sidebar;
17
+ let contentWidth = __contentWidth !== undefined ? __contentWidth : "FullWidth";
18
+ let noPadding = __noPadding !== undefined ? __noPadding : false;
19
+ let sidebarCollapsed = __sidebarCollapsed !== undefined ? __sidebarCollapsed : false;
20
+ let sidebarOpen = Xote.Signal.make(false, undefined, undefined);
21
+ let getLayoutClass = () => {
22
+ let hasSidebar = Core__Option.isSome(sidebar) ? " basefn-app-layout--has-sidebar" : "";
23
+ let sidebarSizeClass;
24
+ if (sidebarSize !== undefined) {
25
+ switch (sidebarSize) {
26
+ case "lg" :
27
+ sidebarSizeClass = " basefn-app-layout--sidebar-lg";
28
+ break;
29
+ case "sm" :
30
+ sidebarSizeClass = " basefn-app-layout--sidebar-sm";
31
+ break;
32
+ default:
33
+ sidebarSizeClass = "";
34
+ }
35
+ } else {
36
+ sidebarSizeClass = "";
37
+ }
38
+ let collapsedClass = sidebarCollapsed ? " basefn-app-layout--sidebar-collapsed" : "";
39
+ Xote.Computed.make(() => {
40
+ if (Xote.Signal.get(sidebarOpen)) {
41
+ return " basefn-app-layout--sidebar-open";
42
+ } else {
43
+ return "";
44
+ }
45
+ }, undefined);
46
+ return "basefn-app-layout" + hasSidebar + sidebarSizeClass + collapsedClass;
47
+ };
48
+ let getContentClass = () => {
49
+ let widthClass;
50
+ widthClass = contentWidth === "FullWidth" ? " basefn-app-layout--full-width" : " basefn-app-layout--contained";
51
+ let paddingClass = noPadding ? " basefn-app-layout__content-inner--no-padding" : "";
52
+ return "basefn-app-layout__content-inner" + widthClass + paddingClass;
53
+ };
54
+ return Xote__JSX.Elements.jsxs("div", {
55
+ class: Xote.Computed.make(() => getLayoutClass() + Xote.Signal.get(Xote.Computed.make(() => {
56
+ if (Xote.Signal.get(sidebarOpen)) {
57
+ return " basefn-app-layout--sidebar-open";
58
+ } else {
59
+ return "";
60
+ }
61
+ }, undefined)), undefined),
62
+ 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, {}),
75
+ Xote__JSX.Elements.jsxs("div", {
76
+ class: "basefn-app-layout__main-wrapper",
77
+ children: Xote__JSX.array([
78
+ topbar !== undefined ? Xote__JSX.Elements.jsx("div", {
79
+ class: "basefn-app-layout__topbar",
80
+ children: topbar
81
+ }) : 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
+ })
88
+ })
89
+ ])
90
+ })
91
+ ])
92
+ });
93
+ }
94
+
95
+ let make = Basefn__AppLayout;
96
+
97
+ export {
98
+ make,
99
+ }
100
+ /* Not a pure module */
@@ -0,0 +1,25 @@
1
+ @import '../styles/variables.css';
2
+
3
+ .basefn-avatar {
4
+ border-radius: 50%;
5
+ margin: 0;
6
+ padding: 0;
7
+ overflow: hidden;
8
+ width: 2.5rem;
9
+ height: 2.5rem;
10
+ }
11
+
12
+ .basefn-avatar--sm {
13
+ width: 1.5rem;
14
+ height: 1.5rem;
15
+ }
16
+
17
+ .basefn-avatar--lg {
18
+ width: 4rem;
19
+ height: 4rem;
20
+ }
21
+
22
+ .basefn-avatar img {
23
+ width: 100%;
24
+ height: 100%;
25
+ }
@@ -0,0 +1,23 @@
1
+ %%raw(`import './Basefn__Avatar.css'`)
2
+
3
+ type size = Sm | Md | Lg
4
+
5
+ let sizeToString = (size: size) => {
6
+ switch size {
7
+ | Sm => "sm"
8
+ | Md => "md"
9
+ | Lg => "lg"
10
+ }
11
+ }
12
+
13
+ @jsx.component
14
+ let make = (~src=?, ~name=?, ~size=Md) => {
15
+ let class = {
16
+ let sizeClass = "basefn-avatar--" ++ sizeToString(size)
17
+ "basefn-avatar " ++ sizeClass
18
+ }
19
+
20
+ <div class>
21
+ <img src={src} alt={name} />
22
+ </div>
23
+ }
@@ -0,0 +1,40 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Xote__JSX from "xote/src/Xote__JSX.res.mjs";
4
+ import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
5
+
6
+ import './Basefn__Avatar.css'
7
+ ;
8
+
9
+ function sizeToString(size) {
10
+ switch (size) {
11
+ case "Sm" :
12
+ return "sm";
13
+ case "Md" :
14
+ return "md";
15
+ case "Lg" :
16
+ return "lg";
17
+ }
18
+ }
19
+
20
+ function Basefn__Avatar(props) {
21
+ let __size = props.size;
22
+ let size = __size !== undefined ? __size : "Md";
23
+ let sizeClass = "basefn-avatar--" + sizeToString(size);
24
+ let $$class = "basefn-avatar " + sizeClass;
25
+ return Xote__JSX.Elements.jsx("div", {
26
+ class: $$class,
27
+ children: Xote__JSX.Elements.jsx("img", {
28
+ src: Primitive_option.some(props.src),
29
+ alt: Primitive_option.some(props.name)
30
+ })
31
+ });
32
+ }
33
+
34
+ let make = Basefn__Avatar;
35
+
36
+ export {
37
+ sizeToString,
38
+ make,
39
+ }
40
+ /* Not a pure module */
@@ -0,0 +1,71 @@
1
+ .basefn-badge {
2
+ display: inline-flex;
3
+ align-items: center;
4
+ justify-content: center;
5
+ font-weight: 500;
6
+ border-radius: 9999px;
7
+ transition: all 0.2s;
8
+ white-space: nowrap;
9
+ }
10
+
11
+ /* Sizes */
12
+ .basefn-badge--sm {
13
+ padding: 0.125rem 0.5rem;
14
+ font-size: 0.75rem;
15
+ line-height: 1rem;
16
+ }
17
+
18
+ .basefn-badge--md {
19
+ padding: 0.25rem 0.75rem;
20
+ font-size: 0.875rem;
21
+ line-height: 1.25rem;
22
+ }
23
+
24
+ .basefn-badge--lg {
25
+ padding: 0.375rem 1rem;
26
+ font-size: 1rem;
27
+ line-height: 1.5rem;
28
+ }
29
+
30
+ /* Variants */
31
+ .basefn-badge--default {
32
+ background-color: var(--basefn-bg-tertiary);
33
+ color: var(--basefn-text-primary);
34
+ }
35
+
36
+ .basefn-badge--primary {
37
+ background-color: var(--basefn-color-primary);
38
+ color: #ffffff;
39
+ }
40
+
41
+ .basefn-badge--secondary {
42
+ background-color: var(--basefn-color-secondary);
43
+ color: #ffffff;
44
+ }
45
+
46
+ .basefn-badge--success {
47
+ background-color: var(--basefn-color-success);
48
+ color: #ffffff;
49
+ }
50
+
51
+ .basefn-badge--warning {
52
+ background-color: var(--basefn-color-warning);
53
+ color: #ffffff;
54
+ }
55
+
56
+ .basefn-badge--error {
57
+ background-color: var(--basefn-color-error);
58
+ color: #ffffff;
59
+ }
60
+
61
+ /* Dot indicator */
62
+ .basefn-badge--dot::before {
63
+ content: '';
64
+ display: inline-block;
65
+ width: 0.5rem;
66
+ height: 0.5rem;
67
+ border-radius: 50%;
68
+ margin-right: 0.5rem;
69
+ background-color: currentColor;
70
+ opacity: 0.7;
71
+ }
@@ -0,0 +1,43 @@
1
+ %%raw(`import './Basefn__Badge.css'`)
2
+
3
+ open Xote
4
+
5
+ type variant = Default | Primary | Secondary | Success | Warning | Error
6
+
7
+ type size = Sm | Md | Lg
8
+
9
+ let variantToString = (variant: variant) => {
10
+ switch variant {
11
+ | Default => "default"
12
+ | Primary => "primary"
13
+ | Secondary => "secondary"
14
+ | Success => "success"
15
+ | Warning => "warning"
16
+ | Error => "error"
17
+ }
18
+ }
19
+
20
+ let sizeToString = (size: size) => {
21
+ switch size {
22
+ | Sm => "sm"
23
+ | Md => "md"
24
+ | Lg => "lg"
25
+ }
26
+ }
27
+
28
+ @jsx.component
29
+ let make = (
30
+ ~label: Signal.t<string>,
31
+ ~variant: variant=Default,
32
+ ~size: size=Md,
33
+ ~dot: bool=false,
34
+ ) => {
35
+ let getClassName = () => {
36
+ let variantClass = "basefn-badge--" ++ variantToString(variant)
37
+ let sizeClass = "basefn-badge--" ++ sizeToString(size)
38
+ let dotClass = dot ? " basefn-badge--dot" : ""
39
+ "basefn-badge " ++ variantClass ++ " " ++ sizeClass ++ dotClass
40
+ }
41
+
42
+ <span class={getClassName()}> {Component.SignalText(label)} </span>
43
+ }
@@ -0,0 +1,65 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Xote__JSX from "xote/src/Xote__JSX.res.mjs";
4
+
5
+ import './Basefn__Badge.css'
6
+ ;
7
+
8
+ function variantToString(variant) {
9
+ switch (variant) {
10
+ case "Default" :
11
+ return "default";
12
+ case "Primary" :
13
+ return "primary";
14
+ case "Secondary" :
15
+ return "secondary";
16
+ case "Success" :
17
+ return "success";
18
+ case "Warning" :
19
+ return "warning";
20
+ case "Error" :
21
+ return "error";
22
+ }
23
+ }
24
+
25
+ function sizeToString(size) {
26
+ switch (size) {
27
+ case "Sm" :
28
+ return "sm";
29
+ case "Md" :
30
+ return "md";
31
+ case "Lg" :
32
+ return "lg";
33
+ }
34
+ }
35
+
36
+ function Basefn__Badge(props) {
37
+ let __dot = props.dot;
38
+ let __size = props.size;
39
+ let __variant = props.variant;
40
+ let variant = __variant !== undefined ? __variant : "Default";
41
+ let size = __size !== undefined ? __size : "Md";
42
+ let dot = __dot !== undefined ? __dot : false;
43
+ let getClassName = () => {
44
+ let variantClass = "basefn-badge--" + variantToString(variant);
45
+ let sizeClass = "basefn-badge--" + sizeToString(size);
46
+ let dotClass = dot ? " basefn-badge--dot" : "";
47
+ return "basefn-badge " + variantClass + " " + sizeClass + dotClass;
48
+ };
49
+ return Xote__JSX.Elements.jsx("span", {
50
+ class: getClassName(),
51
+ children: {
52
+ TAG: "SignalText",
53
+ _0: props.label
54
+ }
55
+ });
56
+ }
57
+
58
+ let make = Basefn__Badge;
59
+
60
+ export {
61
+ variantToString,
62
+ sizeToString,
63
+ make,
64
+ }
65
+ /* Not a pure module */
@@ -0,0 +1,36 @@
1
+ .basefn-breadcrumb {
2
+ display: flex;
3
+ align-items: center;
4
+ flex-wrap: wrap;
5
+ gap: 0.5rem;
6
+ font-size: 0.875rem;
7
+ }
8
+
9
+ .basefn-breadcrumb__item {
10
+ display: flex;
11
+ align-items: center;
12
+ gap: 0.5rem;
13
+ }
14
+
15
+ .basefn-breadcrumb__link {
16
+ color: #6b7280;
17
+ text-decoration: none;
18
+ transition: color 0.2s;
19
+ cursor: pointer;
20
+ }
21
+
22
+ .basefn-breadcrumb__link:hover {
23
+ color: #3b82f6;
24
+ }
25
+
26
+ .basefn-breadcrumb__link--active {
27
+ color: #1f2937;
28
+ font-weight: 500;
29
+ cursor: default;
30
+ pointer-events: none;
31
+ }
32
+
33
+ .basefn-breadcrumb__separator {
34
+ color: #d1d5db;
35
+ user-select: none;
36
+ }
@@ -0,0 +1,45 @@
1
+ %%raw(`import './Basefn__Breadcrumb.css'`)
2
+
3
+ open Xote
4
+
5
+ type breadcrumbItem = {
6
+ label: string,
7
+ href: option<string>,
8
+ onClick: option<unit => unit>,
9
+ }
10
+
11
+ @jsx.component
12
+ let make = (~items: array<breadcrumbItem>, ~separator: string="/") => {
13
+ <nav class="basefn-breadcrumb">
14
+ {items
15
+ ->Array.mapWithIndex((item, index) => {
16
+ let isLast = index == Array.length(items) - 1
17
+ let className = isLast ? "basefn-breadcrumb__link--active" : ""
18
+
19
+ <div key={Int.toString(index)} class="basefn-breadcrumb__item">
20
+ {switch (item.href, item.onClick) {
21
+ | (Some(href), _) =>
22
+ <a href={href} class={"basefn-breadcrumb__link " ++ className}>
23
+ {Component.text(item.label)}
24
+ </a>
25
+ | (None, Some(onClick)) =>
26
+ <button
27
+ class={"basefn-breadcrumb__link " ++ className}
28
+ onClick={_ => onClick()}
29
+ style="background: none; border: none; padding: 0; font: inherit;"
30
+ >
31
+ {Component.text(item.label)}
32
+ </button>
33
+ | (None, None) =>
34
+ <span class={"basefn-breadcrumb__link " ++ className}>
35
+ {Component.text(item.label)}
36
+ </span>
37
+ }}
38
+ {!isLast
39
+ ? <span class="basefn-breadcrumb__separator"> {Component.text(separator)} </span>
40
+ : <> </>}
41
+ </div>
42
+ })
43
+ ->Component.fragment}
44
+ </nav>
45
+ }
@@ -0,0 +1,53 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Xote from "xote/src/Xote.res.mjs";
4
+ import * as Xote__JSX from "xote/src/Xote__JSX.res.mjs";
5
+
6
+ import './Basefn__Breadcrumb.css'
7
+ ;
8
+
9
+ function Basefn__Breadcrumb(props) {
10
+ let __separator = props.separator;
11
+ let items = props.items;
12
+ let separator = __separator !== undefined ? __separator : "/";
13
+ return Xote__JSX.Elements.jsx("nav", {
14
+ class: "basefn-breadcrumb",
15
+ children: Xote.Component.fragment(items.map((item, index) => {
16
+ let isLast = index === (items.length - 1 | 0);
17
+ let className = isLast ? "basefn-breadcrumb__link--active" : "";
18
+ let match = item.href;
19
+ let match$1 = item.onClick;
20
+ return Xote__JSX.Elements.jsxsKeyed("div", {
21
+ class: "basefn-breadcrumb__item",
22
+ children: Xote__JSX.array([
23
+ match !== undefined ? Xote__JSX.Elements.jsx("a", {
24
+ class: "basefn-breadcrumb__link " + className,
25
+ href: match,
26
+ children: Xote.Component.text(item.label)
27
+ }) : (
28
+ match$1 !== undefined ? Xote__JSX.Elements.jsx("button", {
29
+ class: "basefn-breadcrumb__link " + className,
30
+ style: "background: none; border: none; padding: 0; font: inherit;",
31
+ onClick: param => match$1(),
32
+ children: Xote.Component.text(item.label)
33
+ }) : Xote__JSX.Elements.jsx("span", {
34
+ class: "basefn-breadcrumb__link " + className,
35
+ children: Xote.Component.text(item.label)
36
+ })
37
+ ),
38
+ isLast ? Xote__JSX.jsx(Xote__JSX.jsxFragment, {}) : Xote__JSX.Elements.jsx("span", {
39
+ class: "basefn-breadcrumb__separator",
40
+ children: Xote.Component.text(separator)
41
+ })
42
+ ])
43
+ }, index.toString(), undefined);
44
+ }))
45
+ });
46
+ }
47
+
48
+ let make = Basefn__Breadcrumb;
49
+
50
+ export {
51
+ make,
52
+ }
53
+ /* Not a pure module */