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.
- package/README.md +104 -0
- package/package.json +82 -0
- package/rescript.json +32 -0
- package/src/Basefn.css +14 -0
- package/src/Basefn.res +105 -0
- package/src/Basefn.res.mjs +114 -0
- package/src/Basefn__Dom.res +9 -0
- package/src/Basefn__Dom.res.mjs +24 -0
- package/src/Basefn__Utils.res +15 -0
- package/src/Basefn__Utils.res.mjs +32 -0
- package/src/Demo.res +1417 -0
- package/src/Demo.res.mjs +2328 -0
- package/src/Eita.res.mjs +105 -0
- package/src/Eita__Accordion.res.mjs +77 -0
- package/src/Eita__Alert.res.mjs +81 -0
- package/src/Eita__AppLayout.res.mjs +100 -0
- package/src/Eita__Avatar.res.mjs +40 -0
- package/src/Eita__Badge.res.mjs +65 -0
- package/src/Eita__Breadcrumb.res.mjs +53 -0
- package/src/Eita__Button.res.mjs +47 -0
- package/src/Eita__Card.res.mjs +60 -0
- package/src/Eita__Checkbox.res.mjs +36 -0
- package/src/Eita__Dom.res.mjs +16 -0
- package/src/Eita__Drawer.res.mjs +112 -0
- package/src/Eita__Dropdown.res.mjs +96 -0
- package/src/Eita__Grid.res.mjs +24 -0
- package/src/Eita__Input.res.mjs +54 -0
- package/src/Eita__Kbd.res.mjs +42 -0
- package/src/Eita__Label.res.mjs +24 -0
- package/src/Eita__Modal.res.mjs +93 -0
- package/src/Eita__Progress.res.mjs +101 -0
- package/src/Eita__Radio.res.mjs +38 -0
- package/src/Eita__Select.res.mjs +40 -0
- package/src/Eita__Separator.res.mjs +70 -0
- package/src/Eita__Sidebar.res.mjs +103 -0
- package/src/Eita__Slider.res.mjs +89 -0
- package/src/Eita__Spinner.res.mjs +69 -0
- package/src/Eita__Stepper.res.mjs +114 -0
- package/src/Eita__Switch.res.mjs +84 -0
- package/src/Eita__Tabs.res.mjs +57 -0
- package/src/Eita__Textarea.res.mjs +39 -0
- package/src/Eita__Timeline.res.mjs +86 -0
- package/src/Eita__Toast.res.mjs +112 -0
- package/src/Eita__Tooltip.res.mjs +60 -0
- package/src/Eita__Topbar.res.mjs +96 -0
- package/src/Eita__Typography.res.mjs +183 -0
- package/src/Eita__Utils.res.mjs +32 -0
- package/src/Example.res +111 -0
- package/src/Example.res.mjs +176 -0
- package/src/components/Basefn__Accordion.css +70 -0
- package/src/components/Basefn__Accordion.res +79 -0
- package/src/components/Basefn__Accordion.res.mjs +77 -0
- package/src/components/Basefn__Alert.css +79 -0
- package/src/components/Basefn__Alert.res +68 -0
- package/src/components/Basefn__Alert.res.mjs +78 -0
- package/src/components/Basefn__AppLayout.css +100 -0
- package/src/components/Basefn__AppLayout.res +74 -0
- package/src/components/Basefn__AppLayout.res.mjs +100 -0
- package/src/components/Basefn__Avatar.css +25 -0
- package/src/components/Basefn__Avatar.res +23 -0
- package/src/components/Basefn__Avatar.res.mjs +40 -0
- package/src/components/Basefn__Badge.css +71 -0
- package/src/components/Basefn__Badge.res +43 -0
- package/src/components/Basefn__Badge.res.mjs +65 -0
- package/src/components/Basefn__Breadcrumb.css +36 -0
- package/src/components/Basefn__Breadcrumb.res +45 -0
- package/src/components/Basefn__Breadcrumb.res.mjs +53 -0
- package/src/components/Basefn__Button.css +83 -0
- package/src/components/Basefn__Button.res +32 -0
- package/src/components/Basefn__Button.res.mjs +54 -0
- package/src/components/Basefn__Card.css +50 -0
- package/src/components/Basefn__Card.res +45 -0
- package/src/components/Basefn__Card.res.mjs +60 -0
- package/src/components/Basefn__Checkbox.css +72 -0
- package/src/components/Basefn__Checkbox.res +25 -0
- package/src/components/Basefn__Checkbox.res.mjs +36 -0
- package/src/components/Basefn__Drawer.css +168 -0
- package/src/components/Basefn__Drawer.res +86 -0
- package/src/components/Basefn__Drawer.res.mjs +112 -0
- package/src/components/Basefn__Dropdown.css +76 -0
- package/src/components/Basefn__Dropdown.res +85 -0
- package/src/components/Basefn__Dropdown.res.mjs +96 -0
- package/src/components/Basefn__Grid.css +11 -0
- package/src/components/Basefn__Grid.res +296 -0
- package/src/components/Basefn__Grid.res.mjs +263 -0
- package/src/components/Basefn__Icon.css +12 -0
- package/src/components/Basefn__Icon.res +196 -0
- package/src/components/Basefn__Icon.res.mjs +183 -0
- package/src/components/Basefn__Input.css +44 -0
- package/src/components/Basefn__Input.res +48 -0
- package/src/components/Basefn__Input.res.mjs +63 -0
- package/src/components/Basefn__Kbd.css +65 -0
- package/src/components/Basefn__Kbd.res +27 -0
- package/src/components/Basefn__Kbd.res.mjs +42 -0
- package/src/components/Basefn__Label.css +22 -0
- package/src/components/Basefn__Label.res +18 -0
- package/src/components/Basefn__Label.res.mjs +24 -0
- package/src/components/Basefn__Modal.css +100 -0
- package/src/components/Basefn__Modal.res +74 -0
- package/src/components/Basefn__Modal.res.mjs +93 -0
- package/src/components/Basefn__Progress.css +69 -0
- package/src/components/Basefn__Progress.res +88 -0
- package/src/components/Basefn__Progress.res.mjs +101 -0
- package/src/components/Basefn__Radio.css +72 -0
- package/src/components/Basefn__Radio.res +35 -0
- package/src/components/Basefn__Radio.res.mjs +38 -0
- package/src/components/Basefn__Select.css +44 -0
- package/src/components/Basefn__Select.res +33 -0
- package/src/components/Basefn__Select.res.mjs +40 -0
- package/src/components/Basefn__Separator.css +85 -0
- package/src/components/Basefn__Separator.res +45 -0
- package/src/components/Basefn__Separator.res.mjs +70 -0
- package/src/components/Basefn__Sidebar.css +141 -0
- package/src/components/Basefn__Sidebar.res +95 -0
- package/src/components/Basefn__Sidebar.res.mjs +107 -0
- package/src/components/Basefn__Slider.css +97 -0
- package/src/components/Basefn__Slider.res +68 -0
- package/src/components/Basefn__Slider.res.mjs +89 -0
- package/src/components/Basefn__Spinner.css +63 -0
- package/src/components/Basefn__Spinner.res +44 -0
- package/src/components/Basefn__Spinner.res.mjs +69 -0
- package/src/components/Basefn__Stepper.css +141 -0
- package/src/components/Basefn__Stepper.res +86 -0
- package/src/components/Basefn__Stepper.res.mjs +114 -0
- package/src/components/Basefn__Switch.css +80 -0
- package/src/components/Basefn__Switch.res +62 -0
- package/src/components/Basefn__Switch.res.mjs +84 -0
- package/src/components/Basefn__Tabs.css +54 -0
- package/src/components/Basefn__Tabs.res +73 -0
- package/src/components/Basefn__Tabs.res.mjs +57 -0
- package/src/components/Basefn__Textarea.css +41 -0
- package/src/components/Basefn__Textarea.res +28 -0
- package/src/components/Basefn__Textarea.res.mjs +41 -0
- package/src/components/Basefn__ThemeToggle.css +5 -0
- package/src/components/Basefn__ThemeToggle.res +29 -0
- package/src/components/Basefn__ThemeToggle.res.mjs +49 -0
- package/src/components/Basefn__Timeline.css +144 -0
- package/src/components/Basefn__Timeline.res +70 -0
- package/src/components/Basefn__Timeline.res.mjs +86 -0
- package/src/components/Basefn__Toast.css +100 -0
- package/src/components/Basefn__Toast.res +92 -0
- package/src/components/Basefn__Toast.res.mjs +112 -0
- package/src/components/Basefn__Tooltip.css +84 -0
- package/src/components/Basefn__Tooltip.res +42 -0
- package/src/components/Basefn__Tooltip.res.mjs +60 -0
- package/src/components/Basefn__Topbar.css +130 -0
- package/src/components/Basefn__Topbar.res +92 -0
- package/src/components/Basefn__Topbar.res.mjs +91 -0
- package/src/components/Basefn__Typography.css +120 -0
- package/src/components/Basefn__Typography.res +96 -0
- package/src/components/Basefn__Typography.res.mjs +175 -0
- package/src/styles/Basefn__Theme.res +63 -0
- package/src/styles/Basefn__Theme.res.mjs +65 -0
- package/src/styles/variables.css +199 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
%%raw(`import './Basefn__Icon.css'`)
|
|
2
|
+
|
|
3
|
+
open Xote
|
|
4
|
+
|
|
5
|
+
// Type for icon data from lucide
|
|
6
|
+
type iconElement = array<(string, dict<string>)>
|
|
7
|
+
|
|
8
|
+
// External bindings for lucide icons
|
|
9
|
+
@module("lucide/dist/esm/icons/check.js") external check: iconElement = "default"
|
|
10
|
+
@module("lucide/dist/esm/icons/x.js") external x: iconElement = "default"
|
|
11
|
+
@module("lucide/dist/esm/icons/chevron-down.js") external chevronDown: iconElement = "default"
|
|
12
|
+
@module("lucide/dist/esm/icons/chevron-up.js") external chevronUp: iconElement = "default"
|
|
13
|
+
@module("lucide/dist/esm/icons/chevron-left.js") external chevronLeft: iconElement = "default"
|
|
14
|
+
@module("lucide/dist/esm/icons/chevron-right.js") external chevronRight: iconElement = "default"
|
|
15
|
+
@module("lucide/dist/esm/icons/search.js") external search: iconElement = "default"
|
|
16
|
+
@module("lucide/dist/esm/icons/menu.js") external menu: iconElement = "default"
|
|
17
|
+
@module("lucide/dist/esm/icons/house.js") external home: iconElement = "default"
|
|
18
|
+
@module("lucide/dist/esm/icons/user.js") external user: iconElement = "default"
|
|
19
|
+
@module("lucide/dist/esm/icons/settings.js") external settings: iconElement = "default"
|
|
20
|
+
@module("lucide/dist/esm/icons/info.js") external info: iconElement = "default"
|
|
21
|
+
@module("lucide/dist/esm/icons/circle-alert.js") external alertCircle: iconElement = "default"
|
|
22
|
+
@module("lucide/dist/esm/icons/triangle-alert.js")
|
|
23
|
+
external alertTriangle: iconElement = "default"
|
|
24
|
+
@module("lucide/dist/esm/icons/loader.js") external loader: iconElement = "default"
|
|
25
|
+
@module("lucide/dist/esm/icons/plus.js") external plus: iconElement = "default"
|
|
26
|
+
@module("lucide/dist/esm/icons/minus.js") external minus: iconElement = "default"
|
|
27
|
+
@module("lucide/dist/esm/icons/trash.js") external trash: iconElement = "default"
|
|
28
|
+
@module("lucide/dist/esm/icons/pencil.js") external edit: iconElement = "default"
|
|
29
|
+
@module("lucide/dist/esm/icons/copy.js") external copy: iconElement = "default"
|
|
30
|
+
@module("lucide/dist/esm/icons/external-link.js")
|
|
31
|
+
external externalLink: iconElement = "default"
|
|
32
|
+
@module("lucide/dist/esm/icons/download.js") external download: iconElement = "default"
|
|
33
|
+
@module("lucide/dist/esm/icons/upload.js") external upload: iconElement = "default"
|
|
34
|
+
@module("lucide/dist/esm/icons/heart.js") external heart: iconElement = "default"
|
|
35
|
+
@module("lucide/dist/esm/icons/star.js") external star: iconElement = "default"
|
|
36
|
+
@module("lucide/dist/esm/icons/sun.js") external sun: iconElement = "default"
|
|
37
|
+
@module("lucide/dist/esm/icons/moon.js") external moon: iconElement = "default"
|
|
38
|
+
@module("lucide/dist/esm/icons/github.js") external github: iconElement = "default"
|
|
39
|
+
|
|
40
|
+
// Icon name type
|
|
41
|
+
type name =
|
|
42
|
+
| Check
|
|
43
|
+
| X
|
|
44
|
+
| ChevronDown
|
|
45
|
+
| ChevronUp
|
|
46
|
+
| ChevronLeft
|
|
47
|
+
| ChevronRight
|
|
48
|
+
| Search
|
|
49
|
+
| Menu
|
|
50
|
+
| Home
|
|
51
|
+
| User
|
|
52
|
+
| Settings
|
|
53
|
+
| Info
|
|
54
|
+
| AlertCircle
|
|
55
|
+
| AlertTriangle
|
|
56
|
+
| Loader
|
|
57
|
+
| Plus
|
|
58
|
+
| Minus
|
|
59
|
+
| Trash
|
|
60
|
+
| Edit
|
|
61
|
+
| Copy
|
|
62
|
+
| ExternalLink
|
|
63
|
+
| Download
|
|
64
|
+
| Upload
|
|
65
|
+
| Heart
|
|
66
|
+
| Star
|
|
67
|
+
| Sun
|
|
68
|
+
| Moon
|
|
69
|
+
| GitHub
|
|
70
|
+
|
|
71
|
+
// Get icon data from name
|
|
72
|
+
let getIconData = (name: name): iconElement => {
|
|
73
|
+
switch name {
|
|
74
|
+
| Check => check
|
|
75
|
+
| X => x
|
|
76
|
+
| ChevronDown => chevronDown
|
|
77
|
+
| ChevronUp => chevronUp
|
|
78
|
+
| ChevronLeft => chevronLeft
|
|
79
|
+
| ChevronRight => chevronRight
|
|
80
|
+
| Search => search
|
|
81
|
+
| Menu => menu
|
|
82
|
+
| Home => home
|
|
83
|
+
| User => user
|
|
84
|
+
| Settings => settings
|
|
85
|
+
| Info => info
|
|
86
|
+
| AlertCircle => alertCircle
|
|
87
|
+
| AlertTriangle => alertTriangle
|
|
88
|
+
| Loader => loader
|
|
89
|
+
| Plus => plus
|
|
90
|
+
| Minus => minus
|
|
91
|
+
| Trash => trash
|
|
92
|
+
| Edit => edit
|
|
93
|
+
| Copy => copy
|
|
94
|
+
| ExternalLink => externalLink
|
|
95
|
+
| Download => download
|
|
96
|
+
| Upload => upload
|
|
97
|
+
| Heart => heart
|
|
98
|
+
| Star => star
|
|
99
|
+
| Sun => sun
|
|
100
|
+
| Moon => moon
|
|
101
|
+
| GitHub => github
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Size variants
|
|
106
|
+
type size = Sm | Md | Lg | Xl
|
|
107
|
+
|
|
108
|
+
let sizeToPixels = (size: size): string => {
|
|
109
|
+
switch size {
|
|
110
|
+
| Sm => "16"
|
|
111
|
+
| Md => "24"
|
|
112
|
+
| Lg => "32"
|
|
113
|
+
| Xl => "48"
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Helper to render SVG element attributes as a string
|
|
118
|
+
let renderAttrs = (attrs: dict<string>): string => {
|
|
119
|
+
Dict.toArray(attrs)
|
|
120
|
+
->Array.map(((key, value)) => key ++ "=\"" ++ value ++ "\"")
|
|
121
|
+
->Array.join(" ")
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Convert icon data to SVG string
|
|
125
|
+
let iconToSvgInner = (elements: iconElement): string => {
|
|
126
|
+
elements
|
|
127
|
+
->Array.map(((tag, attrs)) => {
|
|
128
|
+
let attrStr = renderAttrs(attrs)
|
|
129
|
+
|
|
130
|
+
switch tag {
|
|
131
|
+
| "path" | "circle" | "line" | "rect" | "polyline" | "polygon" | "ellipse" =>
|
|
132
|
+
"<" ++
|
|
133
|
+
tag ++
|
|
134
|
+
" " ++
|
|
135
|
+
attrStr ++ " fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />"
|
|
136
|
+
| _ => ""
|
|
137
|
+
}
|
|
138
|
+
})
|
|
139
|
+
->Array.join("")
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Counter for unique IDs
|
|
143
|
+
let iconIdCounter = ref(0)
|
|
144
|
+
|
|
145
|
+
// Helper to inject SVG HTML into an element by ID
|
|
146
|
+
%%raw(`
|
|
147
|
+
function injectIconHTML(id, html) {
|
|
148
|
+
setTimeout(() => {
|
|
149
|
+
const el = document.getElementById(id);
|
|
150
|
+
if (el && !el.hasAttribute('data-svg-injected')) {
|
|
151
|
+
el.innerHTML = html;
|
|
152
|
+
el.setAttribute('data-svg-injected', 'true');
|
|
153
|
+
}
|
|
154
|
+
}, 0);
|
|
155
|
+
}
|
|
156
|
+
`)
|
|
157
|
+
|
|
158
|
+
@val external injectIconHTML: (string, string) => unit = "injectIconHTML"
|
|
159
|
+
|
|
160
|
+
@jsx.component
|
|
161
|
+
let make = (
|
|
162
|
+
~name: name,
|
|
163
|
+
~size: size=Md,
|
|
164
|
+
~class=ReactiveProp.static(""),
|
|
165
|
+
~color=ReactiveProp.static("currentColor"),
|
|
166
|
+
) => {
|
|
167
|
+
let iconData = getIconData(name)
|
|
168
|
+
let sizeStr = sizeToPixels(size)
|
|
169
|
+
let svgInner = iconToSvgInner(iconData)
|
|
170
|
+
|
|
171
|
+
let className = Computed.make(() => {
|
|
172
|
+
"basefn-icon " ++ class->ReactiveProp.get
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
let style = Computed.make(() => {
|
|
176
|
+
"color: " ++
|
|
177
|
+
color->ReactiveProp.get ++
|
|
178
|
+
"; width: " ++
|
|
179
|
+
sizeStr ++
|
|
180
|
+
"px; height: " ++
|
|
181
|
+
sizeStr ++ "px; display: inline-flex;"
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
// Create complete SVG HTML
|
|
185
|
+
let svgHtml = `<svg width="${sizeStr}" height="${sizeStr}" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" style="width: 100%; height: 100%;">${svgInner}</svg>`
|
|
186
|
+
|
|
187
|
+
// Generate unique ID
|
|
188
|
+
iconIdCounter := iconIdCounter.contents + 1
|
|
189
|
+
let iconId = "basefn-icon-" ++ Int.toString(iconIdCounter.contents)
|
|
190
|
+
|
|
191
|
+
// Inject the HTML after render
|
|
192
|
+
let _ = injectIconHTML(iconId, svgHtml)
|
|
193
|
+
|
|
194
|
+
// Return a span element with the unique ID
|
|
195
|
+
<span id={iconId} class={className} style />
|
|
196
|
+
}
|
|
@@ -0,0 +1,183 @@
|
|
|
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 XJs from "lucide/dist/esm/icons/x.js";
|
|
6
|
+
import SunJs from "lucide/dist/esm/icons/sun.js";
|
|
7
|
+
import CopyJs from "lucide/dist/esm/icons/copy.js";
|
|
8
|
+
import InfoJs from "lucide/dist/esm/icons/info.js";
|
|
9
|
+
import MenuJs from "lucide/dist/esm/icons/menu.js";
|
|
10
|
+
import MoonJs from "lucide/dist/esm/icons/moon.js";
|
|
11
|
+
import PlusJs from "lucide/dist/esm/icons/plus.js";
|
|
12
|
+
import StarJs from "lucide/dist/esm/icons/star.js";
|
|
13
|
+
import UserJs from "lucide/dist/esm/icons/user.js";
|
|
14
|
+
import CheckJs from "lucide/dist/esm/icons/check.js";
|
|
15
|
+
import HeartJs from "lucide/dist/esm/icons/heart.js";
|
|
16
|
+
import HouseJs from "lucide/dist/esm/icons/house.js";
|
|
17
|
+
import MinusJs from "lucide/dist/esm/icons/minus.js";
|
|
18
|
+
import TrashJs from "lucide/dist/esm/icons/trash.js";
|
|
19
|
+
import GithubJs from "lucide/dist/esm/icons/github.js";
|
|
20
|
+
import LoaderJs from "lucide/dist/esm/icons/loader.js";
|
|
21
|
+
import PencilJs from "lucide/dist/esm/icons/pencil.js";
|
|
22
|
+
import SearchJs from "lucide/dist/esm/icons/search.js";
|
|
23
|
+
import UploadJs from "lucide/dist/esm/icons/upload.js";
|
|
24
|
+
import DownloadJs from "lucide/dist/esm/icons/download.js";
|
|
25
|
+
import SettingsJs from "lucide/dist/esm/icons/settings.js";
|
|
26
|
+
import ChevronUpJs from "lucide/dist/esm/icons/chevron-up.js";
|
|
27
|
+
import ChevronDownJs from "lucide/dist/esm/icons/chevron-down.js";
|
|
28
|
+
import ChevronLeftJs from "lucide/dist/esm/icons/chevron-left.js";
|
|
29
|
+
import CircleAlertJs from "lucide/dist/esm/icons/circle-alert.js";
|
|
30
|
+
import ChevronRightJs from "lucide/dist/esm/icons/chevron-right.js";
|
|
31
|
+
import ExternalLinkJs from "lucide/dist/esm/icons/external-link.js";
|
|
32
|
+
import TriangleAlertJs from "lucide/dist/esm/icons/triangle-alert.js";
|
|
33
|
+
|
|
34
|
+
import './Basefn__Icon.css'
|
|
35
|
+
;
|
|
36
|
+
|
|
37
|
+
function getIconData(name) {
|
|
38
|
+
switch (name) {
|
|
39
|
+
case "Check" :
|
|
40
|
+
return CheckJs;
|
|
41
|
+
case "X" :
|
|
42
|
+
return XJs;
|
|
43
|
+
case "ChevronDown" :
|
|
44
|
+
return ChevronDownJs;
|
|
45
|
+
case "ChevronUp" :
|
|
46
|
+
return ChevronUpJs;
|
|
47
|
+
case "ChevronLeft" :
|
|
48
|
+
return ChevronLeftJs;
|
|
49
|
+
case "ChevronRight" :
|
|
50
|
+
return ChevronRightJs;
|
|
51
|
+
case "Search" :
|
|
52
|
+
return SearchJs;
|
|
53
|
+
case "Menu" :
|
|
54
|
+
return MenuJs;
|
|
55
|
+
case "Home" :
|
|
56
|
+
return HouseJs;
|
|
57
|
+
case "User" :
|
|
58
|
+
return UserJs;
|
|
59
|
+
case "Settings" :
|
|
60
|
+
return SettingsJs;
|
|
61
|
+
case "Info" :
|
|
62
|
+
return InfoJs;
|
|
63
|
+
case "AlertCircle" :
|
|
64
|
+
return CircleAlertJs;
|
|
65
|
+
case "AlertTriangle" :
|
|
66
|
+
return TriangleAlertJs;
|
|
67
|
+
case "Loader" :
|
|
68
|
+
return LoaderJs;
|
|
69
|
+
case "Plus" :
|
|
70
|
+
return PlusJs;
|
|
71
|
+
case "Minus" :
|
|
72
|
+
return MinusJs;
|
|
73
|
+
case "Trash" :
|
|
74
|
+
return TrashJs;
|
|
75
|
+
case "Edit" :
|
|
76
|
+
return PencilJs;
|
|
77
|
+
case "Copy" :
|
|
78
|
+
return CopyJs;
|
|
79
|
+
case "ExternalLink" :
|
|
80
|
+
return ExternalLinkJs;
|
|
81
|
+
case "Download" :
|
|
82
|
+
return DownloadJs;
|
|
83
|
+
case "Upload" :
|
|
84
|
+
return UploadJs;
|
|
85
|
+
case "Heart" :
|
|
86
|
+
return HeartJs;
|
|
87
|
+
case "Star" :
|
|
88
|
+
return StarJs;
|
|
89
|
+
case "Sun" :
|
|
90
|
+
return SunJs;
|
|
91
|
+
case "Moon" :
|
|
92
|
+
return MoonJs;
|
|
93
|
+
case "GitHub" :
|
|
94
|
+
return GithubJs;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function sizeToPixels(size) {
|
|
99
|
+
switch (size) {
|
|
100
|
+
case "Sm" :
|
|
101
|
+
return "16";
|
|
102
|
+
case "Md" :
|
|
103
|
+
return "24";
|
|
104
|
+
case "Lg" :
|
|
105
|
+
return "32";
|
|
106
|
+
case "Xl" :
|
|
107
|
+
return "48";
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function renderAttrs(attrs) {
|
|
112
|
+
return Object.entries(attrs).map(param => param[0] + "=\"" + param[1] + "\"").join(" ");
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function iconToSvgInner(elements) {
|
|
116
|
+
return elements.map(param => {
|
|
117
|
+
let tag = param[0];
|
|
118
|
+
let attrStr = renderAttrs(param[1]);
|
|
119
|
+
switch (tag) {
|
|
120
|
+
case "circle" :
|
|
121
|
+
case "ellipse" :
|
|
122
|
+
case "line" :
|
|
123
|
+
case "path" :
|
|
124
|
+
case "polygon" :
|
|
125
|
+
case "polyline" :
|
|
126
|
+
case "rect" :
|
|
127
|
+
break;
|
|
128
|
+
default:
|
|
129
|
+
return "";
|
|
130
|
+
}
|
|
131
|
+
return "<" + tag + " " + attrStr + " fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />";
|
|
132
|
+
}).join("");
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
let iconIdCounter = {
|
|
136
|
+
contents: 0
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
function injectIconHTML(id, html) {
|
|
140
|
+
setTimeout(() => {
|
|
141
|
+
const el = document.getElementById(id);
|
|
142
|
+
if (el && !el.hasAttribute('data-svg-injected')) {
|
|
143
|
+
el.innerHTML = html;
|
|
144
|
+
el.setAttribute('data-svg-injected', 'true');
|
|
145
|
+
}
|
|
146
|
+
}, 0);
|
|
147
|
+
}
|
|
148
|
+
;
|
|
149
|
+
|
|
150
|
+
function Basefn__Icon(props) {
|
|
151
|
+
let __color = props.color;
|
|
152
|
+
let __class = props.class;
|
|
153
|
+
let __size = props.size;
|
|
154
|
+
let size = __size !== undefined ? __size : "Md";
|
|
155
|
+
let $$class = __class !== undefined ? __class : Xote.ReactiveProp.$$static("");
|
|
156
|
+
let color = __color !== undefined ? __color : Xote.ReactiveProp.$$static("currentColor");
|
|
157
|
+
let iconData = getIconData(props.name);
|
|
158
|
+
let sizeStr = sizeToPixels(size);
|
|
159
|
+
let svgInner = iconToSvgInner(iconData);
|
|
160
|
+
let className = Xote.Computed.make(() => "basefn-icon " + Xote.ReactiveProp.get($$class), undefined);
|
|
161
|
+
let style = Xote.Computed.make(() => "color: " + Xote.ReactiveProp.get(color) + "; width: " + sizeStr + "px; height: " + sizeStr + "px; display: inline-flex;", undefined);
|
|
162
|
+
let svgHtml = `<svg width="` + sizeStr + `" height="` + sizeStr + `" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" style="width: 100%; height: 100%;">` + svgInner + `</svg>`;
|
|
163
|
+
iconIdCounter.contents = iconIdCounter.contents + 1 | 0;
|
|
164
|
+
let iconId = "basefn-icon-" + iconIdCounter.contents.toString();
|
|
165
|
+
injectIconHTML(iconId, svgHtml);
|
|
166
|
+
return Xote__JSX.Elements.jsx("span", {
|
|
167
|
+
id: iconId,
|
|
168
|
+
class: className,
|
|
169
|
+
style: style
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
let make = Basefn__Icon;
|
|
174
|
+
|
|
175
|
+
export {
|
|
176
|
+
getIconData,
|
|
177
|
+
sizeToPixels,
|
|
178
|
+
renderAttrs,
|
|
179
|
+
iconToSvgInner,
|
|
180
|
+
iconIdCounter,
|
|
181
|
+
make,
|
|
182
|
+
}
|
|
183
|
+
/* Not a pure module */
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
@import '../styles/variables.css';
|
|
2
|
+
|
|
3
|
+
.basefn-input {
|
|
4
|
+
display: block;
|
|
5
|
+
width: 100%;
|
|
6
|
+
font-family: var(--basefn-font-family);
|
|
7
|
+
font-size: var(--basefn-font-size-sm);
|
|
8
|
+
font-weight: var(--basefn-font-weight-normal);
|
|
9
|
+
line-height: var(--basefn-line-height-normal);
|
|
10
|
+
height: var(--basefn-form-input-height);
|
|
11
|
+
padding: var(--basefn-form-input-padding-y) var(--basefn-form-input-padding-x);
|
|
12
|
+
background-color: var(--basefn-form-input-bg);
|
|
13
|
+
color: var(--basefn-form-input-text);
|
|
14
|
+
border: var(--basefn-border-width) solid var(--basefn-form-input-border);
|
|
15
|
+
border-radius: var(--basefn-radius-lg);
|
|
16
|
+
outline: none;
|
|
17
|
+
transition: border-color var(--basefn-transition-fast), box-shadow var(--basefn-transition-fast);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.basefn-input::placeholder {
|
|
21
|
+
color: var(--basefn-form-input-placeholder);
|
|
22
|
+
opacity: 1;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.basefn-input:focus {
|
|
26
|
+
border-color: var(--basefn-form-input-border-focus);
|
|
27
|
+
box-shadow: 0 0 0 var(--basefn-focus-ring-width) var(--basefn-focus-ring-color);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.basefn-input:disabled {
|
|
31
|
+
background-color: var(--basefn-form-input-disabled-bg);
|
|
32
|
+
border-color: var(--basefn-form-input-disabled-border);
|
|
33
|
+
color: var(--basefn-form-input-disabled-text);
|
|
34
|
+
cursor: not-allowed;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.basefn-input:disabled::placeholder {
|
|
38
|
+
color: var(--basefn-form-input-disabled-text);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.basefn-input--radius-full {
|
|
42
|
+
border-radius: 10rem;
|
|
43
|
+
padding: .5rem 1.25rem;
|
|
44
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
open Xote
|
|
2
|
+
|
|
3
|
+
%%raw(`import './Basefn__Input.css'`)
|
|
4
|
+
|
|
5
|
+
type inputType = Text | Email | Password | Number | Tel | Url | Search | Date | Time
|
|
6
|
+
|
|
7
|
+
type inputSize = Sm | Md
|
|
8
|
+
|
|
9
|
+
type radius = Full | Md
|
|
10
|
+
|
|
11
|
+
let inputTypeToString = (type_: inputType) => {
|
|
12
|
+
switch type_ {
|
|
13
|
+
| Text => "text"
|
|
14
|
+
| Email => "email"
|
|
15
|
+
| Password => "password"
|
|
16
|
+
| Number => "number"
|
|
17
|
+
| Tel => "tel"
|
|
18
|
+
| Url => "url"
|
|
19
|
+
| Search => "search"
|
|
20
|
+
| Date => "date"
|
|
21
|
+
| Time => "time"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@jsx.component
|
|
26
|
+
let make = (
|
|
27
|
+
~value: ReactiveProp.t<string>,
|
|
28
|
+
~onInput: option<Dom.event => unit>=?,
|
|
29
|
+
~type_: inputType=Text,
|
|
30
|
+
~placeholder: string="",
|
|
31
|
+
~disabled=ReactiveProp.static(false),
|
|
32
|
+
~size=Md,
|
|
33
|
+
~radius=Md,
|
|
34
|
+
~name=?,
|
|
35
|
+
~style=?,
|
|
36
|
+
) => {
|
|
37
|
+
let class = {
|
|
38
|
+
let radiusClass = switch radius {
|
|
39
|
+
| Full => "basefn-input--radius-full"
|
|
40
|
+
| _ => ""
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
"basefn-input " ++ radiusClass
|
|
44
|
+
}
|
|
45
|
+
<input
|
|
46
|
+
class ?style type_={inputTypeToString(type_)} placeholder value={value} disabled name ?onInput
|
|
47
|
+
/>
|
|
48
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
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 Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
6
|
+
|
|
7
|
+
import './Basefn__Input.css'
|
|
8
|
+
;
|
|
9
|
+
|
|
10
|
+
function inputTypeToString(type_) {
|
|
11
|
+
switch (type_) {
|
|
12
|
+
case "Text" :
|
|
13
|
+
return "text";
|
|
14
|
+
case "Email" :
|
|
15
|
+
return "email";
|
|
16
|
+
case "Password" :
|
|
17
|
+
return "password";
|
|
18
|
+
case "Number" :
|
|
19
|
+
return "number";
|
|
20
|
+
case "Tel" :
|
|
21
|
+
return "tel";
|
|
22
|
+
case "Url" :
|
|
23
|
+
return "url";
|
|
24
|
+
case "Search" :
|
|
25
|
+
return "search";
|
|
26
|
+
case "Date" :
|
|
27
|
+
return "date";
|
|
28
|
+
case "Time" :
|
|
29
|
+
return "time";
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function Basefn__Input(props) {
|
|
34
|
+
let __radius = props.radius;
|
|
35
|
+
let __disabled = props.disabled;
|
|
36
|
+
let __placeholder = props.placeholder;
|
|
37
|
+
let __type_ = props.type_;
|
|
38
|
+
let type_ = __type_ !== undefined ? __type_ : "Text";
|
|
39
|
+
let placeholder = __placeholder !== undefined ? __placeholder : "";
|
|
40
|
+
let disabled = __disabled !== undefined ? __disabled : Xote.ReactiveProp.$$static(false);
|
|
41
|
+
let radius = __radius !== undefined ? __radius : "Md";
|
|
42
|
+
let radiusClass;
|
|
43
|
+
radiusClass = radius === "Full" ? "basefn-input--radius-full" : "";
|
|
44
|
+
let $$class = "basefn-input " + radiusClass;
|
|
45
|
+
return Xote__JSX.Elements.jsx("input", {
|
|
46
|
+
class: $$class,
|
|
47
|
+
style: props.style,
|
|
48
|
+
type: inputTypeToString(type_),
|
|
49
|
+
name: Primitive_option.some(props.name),
|
|
50
|
+
value: props.value,
|
|
51
|
+
placeholder: placeholder,
|
|
52
|
+
disabled: disabled,
|
|
53
|
+
onInput: props.onInput
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
let make = Basefn__Input;
|
|
58
|
+
|
|
59
|
+
export {
|
|
60
|
+
inputTypeToString,
|
|
61
|
+
make,
|
|
62
|
+
}
|
|
63
|
+
/* Not a pure module */
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
.basefn-kbd {
|
|
2
|
+
display: inline-flex;
|
|
3
|
+
align-items: center;
|
|
4
|
+
gap: 0.25rem;
|
|
5
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
6
|
+
font-weight: 500;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.basefn-kbd__key {
|
|
10
|
+
display: inline-flex;
|
|
11
|
+
align-items: center;
|
|
12
|
+
justify-content: center;
|
|
13
|
+
border: 1px solid #d1d5db;
|
|
14
|
+
border-bottom-width: 2px;
|
|
15
|
+
border-radius: 0.375rem;
|
|
16
|
+
background-color: #f9fafb;
|
|
17
|
+
color: #374151;
|
|
18
|
+
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.basefn-kbd__separator {
|
|
22
|
+
color: #9ca3af;
|
|
23
|
+
font-weight: 400;
|
|
24
|
+
margin: 0 0.125rem;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/* Sizes */
|
|
28
|
+
.basefn-kbd--sm .basefn-kbd__key {
|
|
29
|
+
padding: 0.125rem 0.375rem;
|
|
30
|
+
font-size: 0.75rem;
|
|
31
|
+
line-height: 1rem;
|
|
32
|
+
min-width: 1.25rem;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.basefn-kbd--sm .basefn-kbd__separator {
|
|
36
|
+
font-size: 0.75rem;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.basefn-kbd--md .basefn-kbd__key {
|
|
40
|
+
padding: 0.25rem 0.5rem;
|
|
41
|
+
font-size: 0.875rem;
|
|
42
|
+
line-height: 1.25rem;
|
|
43
|
+
min-width: 1.5rem;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.basefn-kbd--md .basefn-kbd__separator {
|
|
47
|
+
font-size: 0.875rem;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.basefn-kbd--lg .basefn-kbd__key {
|
|
51
|
+
padding: 0.375rem 0.75rem;
|
|
52
|
+
font-size: 1rem;
|
|
53
|
+
line-height: 1.5rem;
|
|
54
|
+
min-width: 2rem;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.basefn-kbd--lg .basefn-kbd__separator {
|
|
58
|
+
font-size: 1rem;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/* Hover effect */
|
|
62
|
+
.basefn-kbd__key:hover {
|
|
63
|
+
background-color: #f3f4f6;
|
|
64
|
+
border-color: #9ca3af;
|
|
65
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
%%raw(`import './Basefn__Kbd.css'`)
|
|
2
|
+
|
|
3
|
+
open Xote
|
|
4
|
+
|
|
5
|
+
type size = Sm | Md | Lg
|
|
6
|
+
|
|
7
|
+
let sizeToString = (size: size) => {
|
|
8
|
+
switch size {
|
|
9
|
+
| Sm => "sm"
|
|
10
|
+
| Md => "md"
|
|
11
|
+
| Lg => "lg"
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
@jsx.component
|
|
16
|
+
let make = (~keys: Signal.t<array<string>>, ~size: size=Md) => {
|
|
17
|
+
let getClassName = () => {
|
|
18
|
+
let sizeClass = "basefn-kbd--" ++ sizeToString(size)
|
|
19
|
+
"basefn-kbd " ++ sizeClass
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
<kbd class={getClassName()}>
|
|
23
|
+
{Component.list(keys, key => {
|
|
24
|
+
<span class="basefn-kbd__key"> {Component.text(key)} </span>
|
|
25
|
+
})}
|
|
26
|
+
</kbd>
|
|
27
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
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__Kbd.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__Kbd(props) {
|
|
21
|
+
let __size = props.size;
|
|
22
|
+
let size = __size !== undefined ? __size : "Md";
|
|
23
|
+
let getClassName = () => {
|
|
24
|
+
let sizeClass = "basefn-kbd--" + sizeToString(size);
|
|
25
|
+
return "basefn-kbd " + sizeClass;
|
|
26
|
+
};
|
|
27
|
+
return Xote__JSX.Elements.jsx("kbd", {
|
|
28
|
+
class: getClassName(),
|
|
29
|
+
children: Xote.Component.list(props.keys, key => Xote__JSX.Elements.jsx("span", {
|
|
30
|
+
class: "basefn-kbd__key",
|
|
31
|
+
children: Xote.Component.text(key)
|
|
32
|
+
}))
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let make = Basefn__Kbd;
|
|
37
|
+
|
|
38
|
+
export {
|
|
39
|
+
sizeToString,
|
|
40
|
+
make,
|
|
41
|
+
}
|
|
42
|
+
/* Not a pure module */
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
@import '../styles/variables.css';
|
|
2
|
+
|
|
3
|
+
.basefn-label {
|
|
4
|
+
display: inline-block;
|
|
5
|
+
font-family: var(--basefn-font-family);
|
|
6
|
+
font-size: var(--basefn-font-size-sm);
|
|
7
|
+
font-weight: var(--basefn-font-weight-medium);
|
|
8
|
+
color: var(--basefn-text-secondary);
|
|
9
|
+
line-height: var(--basefn-line-height-normal);
|
|
10
|
+
margin-bottom: var(--basefn-spacing-xs);
|
|
11
|
+
cursor: pointer;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.basefn-label--required::after {
|
|
15
|
+
content: ' *';
|
|
16
|
+
color: var(--basefn-color-error);
|
|
17
|
+
font-weight: var(--basefn-font-weight-bold);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.basefn-label:empty {
|
|
21
|
+
display: none;
|
|
22
|
+
}
|