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,18 @@
1
+ %%raw(`import './Basefn__Label.css'`)
2
+
3
+ open Xote
4
+
5
+ @jsx.component
6
+ let make = (~text: string, ~required: bool=false) => {
7
+ let getClassName = () => {
8
+ let base = "basefn-label"
9
+ if required {
10
+ base ++ " basefn-label--required"
11
+ } else {
12
+ base
13
+ }
14
+ }
15
+
16
+ // TODO: Add htmlFor support to Xote JSX props
17
+ <label class={getClassName()}> {Component.text(text)} </label>
18
+ }
@@ -0,0 +1,24 @@
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__Label.css'
7
+ ;
8
+
9
+ function Basefn__Label(props) {
10
+ let __required = props.required;
11
+ let required = __required !== undefined ? __required : false;
12
+ let base = "basefn-label";
13
+ return Xote__JSX.Elements.jsx("label", {
14
+ class: required ? base + " basefn-label--required" : base,
15
+ children: Xote.Component.text(props.text)
16
+ });
17
+ }
18
+
19
+ let make = Basefn__Label;
20
+
21
+ export {
22
+ make,
23
+ }
24
+ /* Not a pure module */
@@ -0,0 +1,100 @@
1
+ .basefn-modal-backdrop {
2
+ position: fixed;
3
+ inset: 0;
4
+ background-color: var(--basefn-surface-overlay);
5
+ display: flex;
6
+ align-items: center;
7
+ justify-content: center;
8
+ z-index: 1000;
9
+ animation: basefn-modal-fade-in 0.2s ease-out;
10
+ }
11
+
12
+ .basefn-modal {
13
+ background: var(--basefn-bg-primary);
14
+ border-radius: 0.5rem;
15
+ box-shadow: var(--basefn-shadow-lg);
16
+ max-width: 90vw;
17
+ max-height: 90vh;
18
+ overflow: auto;
19
+ animation: basefn-modal-slide-in 0.3s ease-out;
20
+ }
21
+
22
+ .basefn-modal--sm {
23
+ width: 400px;
24
+ }
25
+
26
+ .basefn-modal--md {
27
+ width: 600px;
28
+ }
29
+
30
+ .basefn-modal--lg {
31
+ width: 800px;
32
+ }
33
+
34
+ .basefn-modal--xl {
35
+ width: 1000px;
36
+ }
37
+
38
+ .basefn-modal__header {
39
+ display: flex;
40
+ align-items: center;
41
+ justify-content: space-between;
42
+ padding: 1.5rem;
43
+ border-bottom: 1px solid var(--basefn-border-primary);
44
+ }
45
+
46
+ .basefn-modal__title {
47
+ font-size: 1.25rem;
48
+ font-weight: 600;
49
+ color: var(--basefn-text-primary);
50
+ margin: 0;
51
+ }
52
+
53
+ .basefn-modal__close {
54
+ background: none;
55
+ border: none;
56
+ font-size: 1.5rem;
57
+ color: var(--basefn-text-tertiary);
58
+ cursor: pointer;
59
+ padding: 0.25rem;
60
+ line-height: 1;
61
+ transition: color 0.2s;
62
+ }
63
+
64
+ .basefn-modal__close:hover {
65
+ color: var(--basefn-text-primary);
66
+ }
67
+
68
+ .basefn-modal__body {
69
+ padding: 1.5rem;
70
+ color: var(--basefn-text-secondary);
71
+ }
72
+
73
+ .basefn-modal__footer {
74
+ display: flex;
75
+ align-items: center;
76
+ justify-content: flex-end;
77
+ gap: 0.75rem;
78
+ padding: 1.5rem;
79
+ border-top: 1px solid var(--basefn-border-primary);
80
+ }
81
+
82
+ @keyframes basefn-modal-fade-in {
83
+ from {
84
+ opacity: 0;
85
+ }
86
+ to {
87
+ opacity: 1;
88
+ }
89
+ }
90
+
91
+ @keyframes basefn-modal-slide-in {
92
+ from {
93
+ opacity: 0;
94
+ transform: scale(0.95) translateY(-20px);
95
+ }
96
+ to {
97
+ opacity: 1;
98
+ transform: scale(1) translateY(0);
99
+ }
100
+ }
@@ -0,0 +1,74 @@
1
+ %%raw(`import './Basefn__Modal.css'`)
2
+
3
+ open Xote
4
+
5
+ type size = Sm | Md | Lg | Xl
6
+
7
+ let sizeToString = (size: size) => {
8
+ switch size {
9
+ | Sm => "sm"
10
+ | Md => "md"
11
+ | Lg => "lg"
12
+ | Xl => "xl"
13
+ }
14
+ }
15
+
16
+ @jsx.component
17
+ let make = (
18
+ ~isOpen: Signal.t<bool>,
19
+ ~onClose: unit => unit,
20
+ ~title: option<string>=?,
21
+ ~size: size=Md,
22
+ ~closeOnBackdrop: bool=true,
23
+ ~showCloseButton: bool=true,
24
+ ~children: Component.node,
25
+ ~footer: option<Component.node>=?,
26
+ ) => {
27
+ let handleBackdropClick = evt => {
28
+ if closeOnBackdrop {
29
+ // Only close if clicking the backdrop itself, not the modal content
30
+ let target = Obj.magic(evt)["target"]
31
+ let currentTarget = Obj.magic(evt)["currentTarget"]
32
+ if target === currentTarget {
33
+ onClose()
34
+ }
35
+ }
36
+ }
37
+
38
+ let getModalClass = () => {
39
+ let sizeClass = "basefn-modal--" ++ sizeToString(size)
40
+ "basefn-modal " ++ sizeClass
41
+ }
42
+
43
+ let content = Computed.make(() => {
44
+ if Signal.get(isOpen) {
45
+ [
46
+ <div class="basefn-modal-backdrop" onClick={handleBackdropClick}>
47
+ <div class={getModalClass()}>
48
+ {switch title {
49
+ | Some(titleText) =>
50
+ <div class="basefn-modal__header">
51
+ <h2 class="basefn-modal__title"> {Component.text(titleText)} </h2>
52
+ {showCloseButton
53
+ ? <button class="basefn-modal__close" onClick={_ => onClose()}>
54
+ {Component.text("\u00d7")}
55
+ </button>
56
+ : <> </>}
57
+ </div>
58
+ | None => <> </>
59
+ }}
60
+ <div class="basefn-modal__body"> {children} </div>
61
+ {switch footer {
62
+ | Some(footerContent) => <div class="basefn-modal__footer"> {footerContent} </div>
63
+ | None => <> </>
64
+ }}
65
+ </div>
66
+ </div>,
67
+ ]
68
+ } else {
69
+ []
70
+ }
71
+ })
72
+
73
+ Component.signalFragment(content)
74
+ }
@@ -0,0 +1,93 @@
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__Modal.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
+ case "Xl" :
18
+ return "xl";
19
+ }
20
+ }
21
+
22
+ function Basefn__Modal(props) {
23
+ let footer = props.footer;
24
+ let children = props.children;
25
+ let __showCloseButton = props.showCloseButton;
26
+ let __closeOnBackdrop = props.closeOnBackdrop;
27
+ let __size = props.size;
28
+ let title = props.title;
29
+ let onClose = props.onClose;
30
+ let isOpen = props.isOpen;
31
+ let size = __size !== undefined ? __size : "Md";
32
+ let closeOnBackdrop = __closeOnBackdrop !== undefined ? __closeOnBackdrop : true;
33
+ let showCloseButton = __showCloseButton !== undefined ? __showCloseButton : true;
34
+ let handleBackdropClick = evt => {
35
+ if (!closeOnBackdrop) {
36
+ return;
37
+ }
38
+ let target = evt.target;
39
+ let currentTarget = evt.currentTarget;
40
+ if (target === currentTarget) {
41
+ return onClose();
42
+ }
43
+ };
44
+ let getModalClass = () => {
45
+ let sizeClass = "basefn-modal--" + sizeToString(size);
46
+ return "basefn-modal " + sizeClass;
47
+ };
48
+ return Xote.Component.signalFragment(Xote.Computed.make(() => {
49
+ if (Xote.Signal.get(isOpen)) {
50
+ return [Xote__JSX.Elements.jsx("div", {
51
+ class: "basefn-modal-backdrop",
52
+ onClick: handleBackdropClick,
53
+ children: Xote__JSX.Elements.jsxs("div", {
54
+ class: getModalClass(),
55
+ children: Xote__JSX.array([
56
+ title !== undefined ? Xote__JSX.Elements.jsxs("div", {
57
+ class: "basefn-modal__header",
58
+ children: Xote__JSX.array([
59
+ Xote__JSX.Elements.jsx("h2", {
60
+ class: "basefn-modal__title",
61
+ children: Xote.Component.text(title)
62
+ }),
63
+ showCloseButton ? Xote__JSX.Elements.jsx("button", {
64
+ class: "basefn-modal__close",
65
+ onClick: param => onClose(),
66
+ children: Xote.Component.text("\u00d7")
67
+ }) : Xote__JSX.jsx(Xote__JSX.jsxFragment, {})
68
+ ])
69
+ }) : Xote__JSX.jsx(Xote__JSX.jsxFragment, {}),
70
+ Xote__JSX.Elements.jsx("div", {
71
+ class: "basefn-modal__body",
72
+ children: children
73
+ }),
74
+ footer !== undefined ? Xote__JSX.Elements.jsx("div", {
75
+ class: "basefn-modal__footer",
76
+ children: footer
77
+ }) : Xote__JSX.jsx(Xote__JSX.jsxFragment, {})
78
+ ])
79
+ })
80
+ })];
81
+ } else {
82
+ return [];
83
+ }
84
+ }, undefined));
85
+ }
86
+
87
+ let make = Basefn__Modal;
88
+
89
+ export {
90
+ sizeToString,
91
+ make,
92
+ }
93
+ /* Not a pure module */
@@ -0,0 +1,69 @@
1
+ .basefn-progress {
2
+ position: relative;
3
+ width: 100%;
4
+ height: 0.75rem;
5
+ background-color: #e5e7eb;
6
+ border-radius: 9999px;
7
+ overflow: hidden;
8
+ }
9
+
10
+ .basefn-progress--sm {
11
+ height: 0.5rem;
12
+ }
13
+
14
+ .basefn-progress--md {
15
+ height: 0.75rem;
16
+ }
17
+
18
+ .basefn-progress--lg {
19
+ height: 1rem;
20
+ }
21
+
22
+ .basefn-progress__bar {
23
+ height: 100%;
24
+ background-color: #3b82f6;
25
+ border-radius: 9999px;
26
+ transition: width 0.3s ease-in-out;
27
+ }
28
+
29
+ .basefn-progress__bar--default {
30
+ background-color: #6b7280;
31
+ }
32
+
33
+ .basefn-progress__bar--primary {
34
+ background-color: #3b82f6;
35
+ }
36
+
37
+ .basefn-progress__bar--success {
38
+ background-color: #10b981;
39
+ }
40
+
41
+ .basefn-progress__bar--warning {
42
+ background-color: #f59e0b;
43
+ }
44
+
45
+ .basefn-progress__bar--error {
46
+ background-color: #ef4444;
47
+ }
48
+
49
+ .basefn-progress__bar--animated {
50
+ animation: basefn-progress-indeterminate 1.5s ease-in-out infinite;
51
+ }
52
+
53
+ .basefn-progress__label {
54
+ margin-top: 0.5rem;
55
+ font-size: 0.875rem;
56
+ color: #6b7280;
57
+ display: flex;
58
+ justify-content: space-between;
59
+ align-items: center;
60
+ }
61
+
62
+ @keyframes basefn-progress-indeterminate {
63
+ 0% {
64
+ transform: translateX(-100%);
65
+ }
66
+ 100% {
67
+ transform: translateX(400%);
68
+ }
69
+ }
@@ -0,0 +1,88 @@
1
+ %%raw(`import './Basefn__Progress.css'`)
2
+
3
+ open Xote
4
+
5
+ type size = Sm | Md | Lg
6
+
7
+ type variant = Default | Primary | Success | Warning | Error
8
+
9
+ let sizeToString = (size: size) => {
10
+ switch size {
11
+ | Sm => "sm"
12
+ | Md => "md"
13
+ | Lg => "lg"
14
+ }
15
+ }
16
+
17
+ let variantToString = (variant: variant) => {
18
+ switch variant {
19
+ | Default => "default"
20
+ | Primary => "primary"
21
+ | Success => "success"
22
+ | Warning => "warning"
23
+ | Error => "error"
24
+ }
25
+ }
26
+
27
+ @jsx.component
28
+ let make = (
29
+ ~value: Signal.t<float>,
30
+ ~max: float=100.0,
31
+ ~size: size=Md,
32
+ ~variant: variant=Primary,
33
+ ~showLabel: bool=false,
34
+ ~label: option<string>=?,
35
+ ~indeterminate: bool=false,
36
+ ) => {
37
+ let getProgressClass = () => {
38
+ let sizeClass = "basefn-progress--" ++ sizeToString(size)
39
+ "basefn-progress " ++ sizeClass
40
+ }
41
+
42
+ let getBarClass = () => {
43
+ let variantClass = "basefn-progress__bar--" ++ variantToString(variant)
44
+ let animatedClass = indeterminate ? " basefn-progress__bar--animated" : ""
45
+ "basefn-progress__bar " ++ variantClass ++ animatedClass
46
+ }
47
+
48
+ let getPercentage = () => {
49
+ let currentValue = Signal.get(value)
50
+ let percent = currentValue /. max *. 100.0
51
+ let clamped = if percent > 100.0 {
52
+ 100.0
53
+ } else if percent < 0.0 {
54
+ 0.0
55
+ } else {
56
+ percent
57
+ }
58
+ Float.toString(clamped)
59
+ }
60
+
61
+ <>
62
+ <div class={getProgressClass()}>
63
+ <div
64
+ class={getBarClass()}
65
+ style={Computed.make(() => {
66
+ if indeterminate {
67
+ "width: 30%"
68
+ } else {
69
+ "width: " ++ getPercentage() ++ "%"
70
+ }
71
+ })}
72
+ />
73
+ </div>
74
+ {showLabel || label->Option.isSome
75
+ ? <div class="basefn-progress__label">
76
+ <span>
77
+ {Component.text(
78
+ switch label {
79
+ | Some(labelText) => labelText
80
+ | None => "Progress"
81
+ },
82
+ )}
83
+ </span>
84
+ {!indeterminate ? {Component.textSignal(() => getPercentage() ++ "%")} : <> </>}
85
+ </div>
86
+ : <> </>}
87
+ </>
88
+ }
@@ -0,0 +1,101 @@
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__Progress.css'
8
+ ;
9
+
10
+ function sizeToString(size) {
11
+ switch (size) {
12
+ case "Sm" :
13
+ return "sm";
14
+ case "Md" :
15
+ return "md";
16
+ case "Lg" :
17
+ return "lg";
18
+ }
19
+ }
20
+
21
+ function variantToString(variant) {
22
+ switch (variant) {
23
+ case "Default" :
24
+ return "default";
25
+ case "Primary" :
26
+ return "primary";
27
+ case "Success" :
28
+ return "success";
29
+ case "Warning" :
30
+ return "warning";
31
+ case "Error" :
32
+ return "error";
33
+ }
34
+ }
35
+
36
+ function Basefn__Progress(props) {
37
+ let __indeterminate = props.indeterminate;
38
+ let label = props.label;
39
+ let __showLabel = props.showLabel;
40
+ let __variant = props.variant;
41
+ let __size = props.size;
42
+ let __max = props.max;
43
+ let value = props.value;
44
+ let max = __max !== undefined ? __max : 100.0;
45
+ let size = __size !== undefined ? __size : "Md";
46
+ let variant = __variant !== undefined ? __variant : "Primary";
47
+ let showLabel = __showLabel !== undefined ? __showLabel : false;
48
+ let indeterminate = __indeterminate !== undefined ? __indeterminate : false;
49
+ let getProgressClass = () => {
50
+ let sizeClass = "basefn-progress--" + sizeToString(size);
51
+ return "basefn-progress " + sizeClass;
52
+ };
53
+ let getBarClass = () => {
54
+ let variantClass = "basefn-progress__bar--" + variantToString(variant);
55
+ let animatedClass = indeterminate ? " basefn-progress__bar--animated" : "";
56
+ return "basefn-progress__bar " + variantClass + animatedClass;
57
+ };
58
+ let getPercentage = () => {
59
+ let currentValue = Xote.Signal.get(value);
60
+ let percent = currentValue / max * 100.0;
61
+ let clamped = percent > 100.0 ? 100.0 : (
62
+ percent < 0.0 ? 0.0 : percent
63
+ );
64
+ return clamped.toString();
65
+ };
66
+ return Xote__JSX.jsxs(Xote__JSX.jsxFragment, {
67
+ children: Xote__JSX.array([
68
+ Xote__JSX.Elements.jsx("div", {
69
+ class: getProgressClass(),
70
+ children: Xote__JSX.Elements.jsx("div", {
71
+ class: getBarClass(),
72
+ style: Xote.Computed.make(() => {
73
+ if (indeterminate) {
74
+ return "width: 30%";
75
+ } else {
76
+ return "width: " + getPercentage() + "%";
77
+ }
78
+ }, undefined)
79
+ })
80
+ }),
81
+ showLabel || Core__Option.isSome(label) ? Xote__JSX.Elements.jsxs("div", {
82
+ class: "basefn-progress__label",
83
+ children: Xote__JSX.array([
84
+ Xote__JSX.Elements.jsx("span", {
85
+ children: Xote.Component.text(label !== undefined ? label : "Progress")
86
+ }),
87
+ indeterminate ? Xote__JSX.jsx(Xote__JSX.jsxFragment, {}) : Xote.Component.textSignal(() => getPercentage() + "%")
88
+ ])
89
+ }) : Xote__JSX.jsx(Xote__JSX.jsxFragment, {})
90
+ ])
91
+ });
92
+ }
93
+
94
+ let make = Basefn__Progress;
95
+
96
+ export {
97
+ sizeToString,
98
+ variantToString,
99
+ make,
100
+ }
101
+ /* Not a pure module */
@@ -0,0 +1,72 @@
1
+ @import '../styles/variables.css';
2
+
3
+ .basefn-radio-wrapper {
4
+ display: inline-flex;
5
+ align-items: center;
6
+ gap: var(--basefn-spacing-sm);
7
+ cursor: pointer;
8
+ user-select: none;
9
+ }
10
+
11
+ .basefn-radio-wrapper--disabled {
12
+ cursor: not-allowed;
13
+ opacity: 0.6;
14
+ }
15
+
16
+ .basefn-radio-input {
17
+ appearance: none;
18
+ width: 1.125rem;
19
+ height: 1.125rem;
20
+ border: var(--basefn-border-width-thick) solid var(--basefn-form-input-border);
21
+ border-radius: var(--basefn-radius-full);
22
+ background-color: var(--basefn-form-input-bg);
23
+ cursor: pointer;
24
+ position: relative;
25
+ transition: all var(--basefn-transition-fast);
26
+ flex-shrink: 0;
27
+ }
28
+
29
+ .basefn-radio-input:focus-visible {
30
+ outline: var(--basefn-focus-ring-width) solid var(--basefn-focus-ring-color);
31
+ outline-offset: var(--basefn-focus-ring-offset);
32
+ }
33
+
34
+ .basefn-radio-input:checked {
35
+ background-color: var(--basefn-color-primary);
36
+ border-color: var(--basefn-color-primary);
37
+ }
38
+
39
+ .basefn-radio-input:checked::after {
40
+ content: '';
41
+ position: absolute;
42
+ left: 50%;
43
+ top: 50%;
44
+ transform: translate(-50%, -50%);
45
+ width: 0.375rem;
46
+ height: 0.375rem;
47
+ border-radius: var(--basefn-radius-full);
48
+ background-color: white;
49
+ }
50
+
51
+ .basefn-radio-input:disabled {
52
+ background-color: var(--basefn-form-input-disabled-bg);
53
+ border-color: var(--basefn-form-input-disabled-border);
54
+ cursor: not-allowed;
55
+ }
56
+
57
+ .basefn-radio-input:disabled:checked {
58
+ background-color: var(--basefn-color-neutral-400);
59
+ border-color: var(--basefn-color-neutral-400);
60
+ }
61
+
62
+ .basefn-radio-label {
63
+ font-family: var(--basefn-font-family);
64
+ font-size: var(--basefn-font-size-base);
65
+ font-weight: var(--basefn-font-weight-normal);
66
+ color: var(--basefn-color-neutral-700);
67
+ line-height: var(--basefn-line-height-normal);
68
+ }
69
+
70
+ .basefn-radio-wrapper--disabled .basefn-radio-label {
71
+ color: var(--basefn-form-input-disabled-text);
72
+ }
@@ -0,0 +1,35 @@
1
+ %%raw(`import './Basefn__Radio.css'`)
2
+
3
+ open Xote
4
+
5
+ @jsx.component
6
+ let make = (
7
+ ~checked: Signal.t<bool>,
8
+ ~onChange: option<Dom.event => unit>=?,
9
+ ~value: string,
10
+ ~label: string,
11
+ ~disabled: bool=false,
12
+ ~name: string,
13
+ ) => {
14
+ let getWrapperClassName = () => {
15
+ let base = "basefn-radio-wrapper"
16
+ if disabled {
17
+ base ++ " basefn-radio-wrapper--disabled"
18
+ } else {
19
+ base
20
+ }
21
+ }
22
+
23
+ <label class={getWrapperClassName()}>
24
+ <input
25
+ type_="radio"
26
+ class="basefn-radio-input"
27
+ name
28
+ value
29
+ checked={checked}
30
+ disabled={disabled}
31
+ ?onChange
32
+ />
33
+ <span class="basefn-radio-label"> {Component.text(label)} </span>
34
+ </label>
35
+ }