basefn 1.3.0 → 1.5.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 (46) hide show
  1. package/package.json +3 -3
  2. package/src/Basefn.res +50 -0
  3. package/src/Basefn.res.mjs +40 -0
  4. package/src/components/Basefn__AlertDialog.css +119 -0
  5. package/src/components/Basefn__AlertDialog.res +80 -0
  6. package/src/components/Basefn__AlertDialog.res.mjs +106 -0
  7. package/src/components/Basefn__AppLayout.css +10 -0
  8. package/src/components/Basefn__AspectRatio.css +16 -0
  9. package/src/components/Basefn__AspectRatio.res +26 -0
  10. package/src/components/Basefn__AspectRatio.res.mjs +33 -0
  11. package/src/components/Basefn__Button.css +2 -3
  12. package/src/components/Basefn__ButtonGroup.css +58 -0
  13. package/src/components/Basefn__ButtonGroup.res +33 -0
  14. package/src/components/Basefn__ButtonGroup.res.mjs +38 -0
  15. package/src/components/Basefn__Card.css +15 -0
  16. package/src/components/Basefn__ContextMenu.css +78 -0
  17. package/src/components/Basefn__ContextMenu.res +98 -0
  18. package/src/components/Basefn__ContextMenu.res.mjs +93 -0
  19. package/src/components/Basefn__Drawer.css +31 -0
  20. package/src/components/Basefn__Dropdown.res +3 -1
  21. package/src/components/Basefn__Dropdown.res.mjs +22 -43
  22. package/src/components/Basefn__HoverCard.css +93 -0
  23. package/src/components/Basefn__HoverCard.res +99 -0
  24. package/src/components/Basefn__HoverCard.res.mjs +109 -0
  25. package/src/components/Basefn__Modal.css +38 -0
  26. package/src/components/Basefn__Popover.css +98 -0
  27. package/src/components/Basefn__Popover.res +95 -0
  28. package/src/components/Basefn__Popover.res.mjs +107 -0
  29. package/src/components/Basefn__ScrollArea.css +76 -0
  30. package/src/components/Basefn__ScrollArea.res +60 -0
  31. package/src/components/Basefn__ScrollArea.res.mjs +63 -0
  32. package/src/components/Basefn__Skeleton.css +83 -0
  33. package/src/components/Basefn__Skeleton.res +55 -0
  34. package/src/components/Basefn__Skeleton.res.mjs +62 -0
  35. package/src/components/Basefn__Stepper.css +36 -0
  36. package/src/components/Basefn__Tabs.css +18 -0
  37. package/src/components/Basefn__Toggle.css +87 -0
  38. package/src/components/Basefn__Toggle.res +65 -0
  39. package/src/components/Basefn__Toggle.res.mjs +71 -0
  40. package/src/components/Basefn__ToggleGroup.css +110 -0
  41. package/src/components/Basefn__ToggleGroup.res +106 -0
  42. package/src/components/Basefn__ToggleGroup.res.mjs +89 -0
  43. package/src/components/Basefn__Topbar.css +44 -0
  44. package/src/styles/Basefn__Theme.res +16 -2
  45. package/src/styles/Basefn__Theme.res.mjs +15 -1
  46. package/src/styles/variables.css +57 -38
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "basefn",
3
- "version": "1.3.0",
3
+ "version": "1.5.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/brnrdog/basefn.git"
@@ -38,7 +38,7 @@
38
38
  "lucide": "^0.562.0"
39
39
  },
40
40
  "peerDependencies": {
41
- "xote": "^4.10.0"
41
+ "xote": "^4.12.0"
42
42
  },
43
43
  "release": {
44
44
  "branches": [
@@ -81,6 +81,6 @@
81
81
  "@semantic-release/npm": "^13.1.3",
82
82
  "rescript": "^12.0.1",
83
83
  "vite": "^5.0.0",
84
- "xote": "^4.11.0"
84
+ "xote": "^4.12.0"
85
85
  }
86
86
  }
package/src/Basefn.res CHANGED
@@ -44,6 +44,24 @@ type appLayoutContentWidth = Basefn__AppLayout.contentWidth
44
44
  type appLayoutTopbarPosition = Basefn__AppLayout.topbarPosition
45
45
  type iconName = Basefn__Icon.name
46
46
  type iconSize = Basefn__Icon.size
47
+ type skeletonVariant = Basefn__Skeleton.variant
48
+ type skeletonAnimation = Basefn__Skeleton.animation
49
+ type scrollAreaOrientation = Basefn__ScrollArea.orientation
50
+ type scrollAreaScrollbarSize = Basefn__ScrollArea.scrollbarSize
51
+ type toggleVariant = Basefn__Toggle.variant
52
+ type toggleSize = Basefn__Toggle.size
53
+ type buttonGroupOrientation = Basefn__ButtonGroup.orientation
54
+ type toggleGroupSelectionType = Basefn__ToggleGroup.selectionType
55
+ type toggleGroupItem = Basefn__ToggleGroup.toggleItem
56
+ type toggleGroupVariant = Basefn__ToggleGroup.variant
57
+ type toggleGroupSize = Basefn__ToggleGroup.size
58
+ type popoverPosition = Basefn__Popover.position
59
+ type popoverAlign = Basefn__Popover.align
60
+ type hoverCardPosition = Basefn__HoverCard.position
61
+ type hoverCardAlign = Basefn__HoverCard.align
62
+ type alertDialogVariant = Basefn__AlertDialog.variant
63
+ type contextMenuItem = Basefn__ContextMenu.menuItem
64
+ type contextMenuContent = Basefn__ContextMenu.menuContent
47
65
  type gridColumns = Basefn__Grid.columns
48
66
  type gridRows = Basefn__Grid.rows
49
67
  type gridAutoFlow = Basefn__Grid.autoFlow
@@ -174,3 +192,35 @@ module ThemeToggle = {
174
192
  module Icon = {
175
193
  include Basefn__Icon
176
194
  }
195
+
196
+ // New shadcn-style components
197
+ module Skeleton = {
198
+ include Basefn__Skeleton
199
+ }
200
+ module AspectRatio = {
201
+ include Basefn__AspectRatio
202
+ }
203
+ module ScrollArea = {
204
+ include Basefn__ScrollArea
205
+ }
206
+ module Toggle = {
207
+ include Basefn__Toggle
208
+ }
209
+ module ButtonGroup = {
210
+ include Basefn__ButtonGroup
211
+ }
212
+ module ToggleGroup = {
213
+ include Basefn__ToggleGroup
214
+ }
215
+ module Popover = {
216
+ include Basefn__Popover
217
+ }
218
+ module HoverCard = {
219
+ include Basefn__HoverCard
220
+ }
221
+ module AlertDialog = {
222
+ include Basefn__AlertDialog
223
+ }
224
+ module ContextMenu = {
225
+ include Basefn__ContextMenu
226
+ }
@@ -19,7 +19,9 @@ import * as Basefn__Drawer from "./components/Basefn__Drawer.res.mjs";
19
19
  import * as Basefn__Select from "./components/Basefn__Select.res.mjs";
20
20
  import * as Basefn__Slider from "./components/Basefn__Slider.res.mjs";
21
21
  import * as Basefn__Switch from "./components/Basefn__Switch.res.mjs";
22
+ import * as Basefn__Toggle from "./components/Basefn__Toggle.res.mjs";
22
23
  import * as Basefn__Topbar from "./components/Basefn__Topbar.res.mjs";
24
+ import * as Basefn__Popover from "./components/Basefn__Popover.res.mjs";
23
25
  import * as Basefn__Sidebar from "./components/Basefn__Sidebar.res.mjs";
24
26
  import * as Basefn__Spinner from "./components/Basefn__Spinner.res.mjs";
25
27
  import * as Basefn__Stepper from "./components/Basefn__Stepper.res.mjs";
@@ -27,14 +29,22 @@ import * as Basefn__Tooltip from "./components/Basefn__Tooltip.res.mjs";
27
29
  import * as Basefn__Checkbox from "./components/Basefn__Checkbox.res.mjs";
28
30
  import * as Basefn__Dropdown from "./components/Basefn__Dropdown.res.mjs";
29
31
  import * as Basefn__Progress from "./components/Basefn__Progress.res.mjs";
32
+ import * as Basefn__Skeleton from "./components/Basefn__Skeleton.res.mjs";
30
33
  import * as Basefn__Textarea from "./components/Basefn__Textarea.res.mjs";
31
34
  import * as Basefn__Timeline from "./components/Basefn__Timeline.res.mjs";
32
35
  import * as Basefn__Accordion from "./components/Basefn__Accordion.res.mjs";
33
36
  import * as Basefn__AppLayout from "./components/Basefn__AppLayout.res.mjs";
37
+ import * as Basefn__HoverCard from "./components/Basefn__HoverCard.res.mjs";
34
38
  import * as Basefn__Separator from "./components/Basefn__Separator.res.mjs";
35
39
  import * as Basefn__Breadcrumb from "./components/Basefn__Breadcrumb.res.mjs";
40
+ import * as Basefn__ScrollArea from "./components/Basefn__ScrollArea.res.mjs";
36
41
  import * as Basefn__Typography from "./components/Basefn__Typography.res.mjs";
42
+ import * as Basefn__AlertDialog from "./components/Basefn__AlertDialog.res.mjs";
43
+ import * as Basefn__AspectRatio from "./components/Basefn__AspectRatio.res.mjs";
44
+ import * as Basefn__ButtonGroup from "./components/Basefn__ButtonGroup.res.mjs";
45
+ import * as Basefn__ContextMenu from "./components/Basefn__ContextMenu.res.mjs";
37
46
  import * as Basefn__ThemeToggle from "./components/Basefn__ThemeToggle.res.mjs";
47
+ import * as Basefn__ToggleGroup from "./components/Basefn__ToggleGroup.res.mjs";
38
48
 
39
49
  import './basefn.css'
40
50
  ;
@@ -109,6 +119,26 @@ let ThemeToggle = Basefn__ThemeToggle;
109
119
 
110
120
  let Icon = Basefn__Icon;
111
121
 
122
+ let Skeleton = Basefn__Skeleton;
123
+
124
+ let AspectRatio = Basefn__AspectRatio;
125
+
126
+ let ScrollArea = Basefn__ScrollArea;
127
+
128
+ let Toggle = Basefn__Toggle;
129
+
130
+ let ButtonGroup = Basefn__ButtonGroup;
131
+
132
+ let ToggleGroup = Basefn__ToggleGroup;
133
+
134
+ let Popover = Basefn__Popover;
135
+
136
+ let HoverCard = Basefn__HoverCard;
137
+
138
+ let AlertDialog = Basefn__AlertDialog;
139
+
140
+ let ContextMenu = Basefn__ContextMenu;
141
+
112
142
  export {
113
143
  Button,
114
144
  Input,
@@ -145,5 +175,15 @@ export {
145
175
  Theme,
146
176
  ThemeToggle,
147
177
  Icon,
178
+ Skeleton,
179
+ AspectRatio,
180
+ ScrollArea,
181
+ Toggle,
182
+ ButtonGroup,
183
+ ToggleGroup,
184
+ Popover,
185
+ HoverCard,
186
+ AlertDialog,
187
+ ContextMenu,
148
188
  }
149
189
  /* Not a pure module */
@@ -0,0 +1,119 @@
1
+ @import '../styles/variables.css';
2
+
3
+ .basefn-alert-dialog-backdrop {
4
+ position: fixed;
5
+ inset: 0;
6
+ z-index: 100;
7
+ display: flex;
8
+ align-items: center;
9
+ justify-content: center;
10
+ background: var(--basefn-surface-overlay);
11
+ animation: basefn-alert-dialog-backdrop-fade var(--basefn-transition-fast);
12
+ }
13
+
14
+ @keyframes basefn-alert-dialog-backdrop-fade {
15
+ from {
16
+ opacity: 0;
17
+ }
18
+ to {
19
+ opacity: 1;
20
+ }
21
+ }
22
+
23
+ .basefn-alert-dialog {
24
+ background: var(--basefn-surface-elevated);
25
+ border-radius: var(--basefn-radius-xl);
26
+ box-shadow: var(--basefn-shadow-lg);
27
+ width: 100%;
28
+ max-width: 450px;
29
+ margin: var(--basefn-spacing-lg);
30
+ animation: basefn-alert-dialog-slide-up var(--basefn-transition-fast);
31
+ }
32
+
33
+ @keyframes basefn-alert-dialog-slide-up {
34
+ from {
35
+ opacity: 0;
36
+ transform: scale(0.95) translateY(10px);
37
+ }
38
+ to {
39
+ opacity: 1;
40
+ transform: scale(1) translateY(0);
41
+ }
42
+ }
43
+
44
+ .basefn-alert-dialog__header {
45
+ padding: var(--basefn-spacing-xl) var(--basefn-spacing-xl) 0;
46
+ }
47
+
48
+ .basefn-alert-dialog__title {
49
+ margin: 0;
50
+ font-size: var(--basefn-font-size-lg);
51
+ font-weight: var(--basefn-font-weight-semibold);
52
+ color: var(--basefn-text-primary);
53
+ line-height: var(--basefn-line-height-tight);
54
+ }
55
+
56
+ .basefn-alert-dialog__body {
57
+ padding: var(--basefn-spacing-md) var(--basefn-spacing-xl);
58
+ }
59
+
60
+ .basefn-alert-dialog__description {
61
+ margin: 0;
62
+ font-size: var(--basefn-font-size-base);
63
+ color: var(--basefn-text-secondary);
64
+ line-height: var(--basefn-line-height-normal);
65
+ }
66
+
67
+ .basefn-alert-dialog__footer {
68
+ display: flex;
69
+ justify-content: flex-end;
70
+ gap: var(--basefn-spacing-sm);
71
+ padding: var(--basefn-spacing-lg) var(--basefn-spacing-xl) var(--basefn-spacing-xl);
72
+ }
73
+
74
+ .basefn-alert-dialog__cancel,
75
+ .basefn-alert-dialog__confirm {
76
+ padding: var(--basefn-spacing-sm) var(--basefn-spacing-lg);
77
+ font-family: var(--basefn-font-family);
78
+ font-size: var(--basefn-font-size-sm);
79
+ font-weight: var(--basefn-font-weight-medium);
80
+ border-radius: var(--basefn-radius-md);
81
+ cursor: pointer;
82
+ transition: all var(--basefn-transition-fast);
83
+ }
84
+
85
+ .basefn-alert-dialog__cancel {
86
+ background: transparent;
87
+ border: var(--basefn-border-width) solid var(--basefn-border-primary);
88
+ color: var(--basefn-text-primary);
89
+ }
90
+
91
+ .basefn-alert-dialog__cancel:hover {
92
+ background: var(--basefn-bg-tertiary);
93
+ }
94
+
95
+ .basefn-alert-dialog__confirm--default {
96
+ background: var(--basefn-color-primary);
97
+ border: none;
98
+ color: white;
99
+ }
100
+
101
+ .basefn-alert-dialog__confirm--default:hover {
102
+ background: var(--basefn-color-primary-hover);
103
+ }
104
+
105
+ .basefn-alert-dialog__confirm--destructive {
106
+ background: var(--basefn-color-error);
107
+ border: none;
108
+ color: white;
109
+ }
110
+
111
+ .basefn-alert-dialog__confirm--destructive:hover {
112
+ background: #dc2626;
113
+ }
114
+
115
+ .basefn-alert-dialog__cancel:focus-visible,
116
+ .basefn-alert-dialog__confirm:focus-visible {
117
+ outline: none;
118
+ box-shadow: 0 0 0 var(--basefn-focus-ring-width) var(--basefn-focus-ring-color);
119
+ }
@@ -0,0 +1,80 @@
1
+ %%raw(`import './Basefn__AlertDialog.css'`)
2
+
3
+ open Xote
4
+
5
+ type variant = Default | Destructive
6
+
7
+ let variantToString = (variant: variant) => {
8
+ switch variant {
9
+ | Default => "default"
10
+ | Destructive => "destructive"
11
+ }
12
+ }
13
+
14
+ @jsx.component
15
+ let make = (
16
+ ~isOpen: Signal.t<bool>,
17
+ ~title: string,
18
+ ~description: string,
19
+ ~confirmLabel: string="Confirm",
20
+ ~cancelLabel: string="Cancel",
21
+ ~onConfirm: unit => unit,
22
+ ~onCancel: unit => unit,
23
+ ~variant: variant=Default,
24
+ ~closeOnBackdrop: bool=false,
25
+ ) => {
26
+ let handleBackdropClick = evt => {
27
+ if closeOnBackdrop {
28
+ let target = Obj.magic(evt)["target"]
29
+ let currentTarget = Obj.magic(evt)["currentTarget"]
30
+ if target === currentTarget {
31
+ onCancel()
32
+ }
33
+ }
34
+ }
35
+
36
+ let handleCancel = _ => {
37
+ Signal.set(isOpen, false)
38
+ onCancel()
39
+ }
40
+
41
+ let handleConfirm = _ => {
42
+ Signal.set(isOpen, false)
43
+ onConfirm()
44
+ }
45
+
46
+ let getConfirmButtonClass = () => {
47
+ let baseClass = "basefn-alert-dialog__confirm"
48
+ let variantClass = " basefn-alert-dialog__confirm--" ++ variantToString(variant)
49
+ baseClass ++ variantClass
50
+ }
51
+
52
+ let content = Computed.make(() => {
53
+ if Signal.get(isOpen) {
54
+ [
55
+ <div class="basefn-alert-dialog-backdrop" onClick={handleBackdropClick}>
56
+ <div class="basefn-alert-dialog" role="alertdialog">
57
+ <div class="basefn-alert-dialog__header">
58
+ <h2 class="basefn-alert-dialog__title"> {Component.text(title)} </h2>
59
+ </div>
60
+ <div class="basefn-alert-dialog__body">
61
+ <p class="basefn-alert-dialog__description"> {Component.text(description)} </p>
62
+ </div>
63
+ <div class="basefn-alert-dialog__footer">
64
+ <button class="basefn-alert-dialog__cancel" onClick={handleCancel}>
65
+ {Component.text(cancelLabel)}
66
+ </button>
67
+ <button class={getConfirmButtonClass()} onClick={handleConfirm}>
68
+ {Component.text(confirmLabel)}
69
+ </button>
70
+ </div>
71
+ </div>
72
+ </div>,
73
+ ]
74
+ } else {
75
+ []
76
+ }
77
+ })
78
+
79
+ Component.signalFragment(content)
80
+ }
@@ -0,0 +1,106 @@
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__AlertDialog.css'
7
+ ;
8
+
9
+ function variantToString(variant) {
10
+ if (variant === "Default") {
11
+ return "default";
12
+ } else {
13
+ return "destructive";
14
+ }
15
+ }
16
+
17
+ function Basefn__AlertDialog(props) {
18
+ let __closeOnBackdrop = props.closeOnBackdrop;
19
+ let __variant = props.variant;
20
+ let onCancel = props.onCancel;
21
+ let onConfirm = props.onConfirm;
22
+ let __cancelLabel = props.cancelLabel;
23
+ let __confirmLabel = props.confirmLabel;
24
+ let description = props.description;
25
+ let title = props.title;
26
+ let isOpen = props.isOpen;
27
+ let confirmLabel = __confirmLabel !== undefined ? __confirmLabel : "Confirm";
28
+ let cancelLabel = __cancelLabel !== undefined ? __cancelLabel : "Cancel";
29
+ let variant = __variant !== undefined ? __variant : "Default";
30
+ let closeOnBackdrop = __closeOnBackdrop !== undefined ? __closeOnBackdrop : false;
31
+ let handleBackdropClick = evt => {
32
+ if (!closeOnBackdrop) {
33
+ return;
34
+ }
35
+ let target = evt.target;
36
+ let currentTarget = evt.currentTarget;
37
+ if (target === currentTarget) {
38
+ return onCancel();
39
+ }
40
+ };
41
+ let handleCancel = param => {
42
+ Xote.Signal.set(isOpen, false);
43
+ onCancel();
44
+ };
45
+ let handleConfirm = param => {
46
+ Xote.Signal.set(isOpen, false);
47
+ onConfirm();
48
+ };
49
+ let getConfirmButtonClass = () => {
50
+ let variantClass = " basefn-alert-dialog__confirm--" + variantToString(variant);
51
+ return "basefn-alert-dialog__confirm" + variantClass;
52
+ };
53
+ return Xote.Component.signalFragment(Xote.Computed.make(() => {
54
+ if (Xote.Signal.get(isOpen)) {
55
+ return [Xote__JSX.Elements.jsx("div", {
56
+ class: "basefn-alert-dialog-backdrop",
57
+ onClick: handleBackdropClick,
58
+ children: Xote__JSX.Elements.jsxs("div", {
59
+ class: "basefn-alert-dialog",
60
+ role: "alertdialog",
61
+ children: Xote__JSX.array([
62
+ Xote__JSX.Elements.jsx("div", {
63
+ class: "basefn-alert-dialog__header",
64
+ children: Xote__JSX.Elements.jsx("h2", {
65
+ class: "basefn-alert-dialog__title",
66
+ children: Xote.Component.text(title)
67
+ })
68
+ }),
69
+ Xote__JSX.Elements.jsx("div", {
70
+ class: "basefn-alert-dialog__body",
71
+ children: Xote__JSX.Elements.jsx("p", {
72
+ class: "basefn-alert-dialog__description",
73
+ children: Xote.Component.text(description)
74
+ })
75
+ }),
76
+ Xote__JSX.Elements.jsxs("div", {
77
+ class: "basefn-alert-dialog__footer",
78
+ children: Xote__JSX.array([
79
+ Xote__JSX.Elements.jsx("button", {
80
+ class: "basefn-alert-dialog__cancel",
81
+ onClick: handleCancel,
82
+ children: Xote.Component.text(cancelLabel)
83
+ }),
84
+ Xote__JSX.Elements.jsx("button", {
85
+ class: getConfirmButtonClass(),
86
+ onClick: handleConfirm,
87
+ children: Xote.Component.text(confirmLabel)
88
+ })
89
+ ])
90
+ })
91
+ ])
92
+ })
93
+ })];
94
+ } else {
95
+ return [];
96
+ }
97
+ }, undefined));
98
+ }
99
+
100
+ let make = Basefn__AlertDialog;
101
+
102
+ export {
103
+ variantToString,
104
+ make,
105
+ }
106
+ /* Not a pure module */
@@ -148,4 +148,14 @@
148
148
  .basefn-app-layout--topbar-above.basefn-app-layout--topbar-lg .basefn-app-layout__sidebar-backdrop {
149
149
  top: 72px;
150
150
  }
151
+
152
+ /* Reduce content padding on mobile */
153
+ .basefn-app-layout__content-inner {
154
+ padding: 0.75rem 1rem;
155
+ }
156
+
157
+ /* Contained variant needs full width on mobile */
158
+ .basefn-app-layout--contained .basefn-app-layout__content-inner {
159
+ max-width: 100%;
160
+ }
151
161
  }
@@ -0,0 +1,16 @@
1
+ @import '../styles/variables.css';
2
+
3
+ .basefn-aspect-ratio {
4
+ position: relative;
5
+ width: 100%;
6
+ overflow: hidden;
7
+ }
8
+
9
+ .basefn-aspect-ratio > * {
10
+ position: absolute;
11
+ top: 0;
12
+ left: 0;
13
+ width: 100%;
14
+ height: 100%;
15
+ object-fit: cover;
16
+ }
@@ -0,0 +1,26 @@
1
+ %%raw(`import './Basefn__AspectRatio.css'`)
2
+
3
+ open Xote
4
+
5
+ @jsx.component
6
+ let make = (
7
+ ~ratio: float=1.0,
8
+ ~className: option<string>=?,
9
+ ~children: Component.node,
10
+ ) => {
11
+ let getClassName = () => {
12
+ let baseClass = "basefn-aspect-ratio"
13
+ switch className {
14
+ | Some(c) => baseClass ++ " " ++ c
15
+ | None => baseClass
16
+ }
17
+ }
18
+
19
+ let getStyle = () => {
20
+ "aspect-ratio: " ++ Float.toString(ratio) ++ ";"
21
+ }
22
+
23
+ <div class={getClassName()} style={getStyle()}>
24
+ {children}
25
+ </div>
26
+ }
@@ -0,0 +1,33 @@
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__AspectRatio.css'
6
+ ;
7
+
8
+ function Basefn__AspectRatio(props) {
9
+ let className = props.className;
10
+ let __ratio = props.ratio;
11
+ let ratio = __ratio !== undefined ? __ratio : 1.0;
12
+ let getClassName = () => {
13
+ let baseClass = "basefn-aspect-ratio";
14
+ if (className !== undefined) {
15
+ return baseClass + " " + className;
16
+ } else {
17
+ return baseClass;
18
+ }
19
+ };
20
+ let getStyle = () => "aspect-ratio: " + ratio.toString() + ";";
21
+ return Xote__JSX.Elements.jsx("div", {
22
+ class: getClassName(),
23
+ style: getStyle(),
24
+ children: props.children
25
+ });
26
+ }
27
+
28
+ let make = Basefn__AspectRatio;
29
+
30
+ export {
31
+ make,
32
+ }
33
+ /* Not a pure module */
@@ -1,4 +1,4 @@
1
- @import '../styles/variables.css';
1
+ @import "../styles/variables.css";
2
2
 
3
3
  .basefn-button {
4
4
  display: inline-flex;
@@ -11,7 +11,7 @@
11
11
  height: var(--basefn-button-height);
12
12
  padding: 0 var(--basefn-button-padding-x);
13
13
  border: var(--basefn-border-width) solid transparent;
14
- border-radius: var(--basefn-radius-lg);
14
+ border-radius: var(--basefn-radius-xl);
15
15
  cursor: pointer;
16
16
  transition: all var(--basefn-transition-fast);
17
17
  outline: none;
@@ -64,7 +64,6 @@
64
64
  background-color: transparent;
65
65
  border-color: transparent;
66
66
  border: 0;
67
- padding: 0;
68
67
  color: var(--basefn-text-tertiary);
69
68
  }
70
69
 
@@ -0,0 +1,58 @@
1
+ @import '../styles/variables.css';
2
+
3
+ .basefn-button-group {
4
+ display: inline-flex;
5
+ }
6
+
7
+ /* Horizontal orientation */
8
+ .basefn-button-group--horizontal {
9
+ flex-direction: row;
10
+ }
11
+
12
+ .basefn-button-group--horizontal > :first-child {
13
+ border-top-right-radius: 0;
14
+ border-bottom-right-radius: 0;
15
+ }
16
+
17
+ .basefn-button-group--horizontal > :last-child {
18
+ border-top-left-radius: 0;
19
+ border-bottom-left-radius: 0;
20
+ }
21
+
22
+ .basefn-button-group--horizontal > :not(:first-child):not(:last-child) {
23
+ border-radius: 0;
24
+ }
25
+
26
+ .basefn-button-group--horizontal > :not(:first-child) {
27
+ margin-left: -1px;
28
+ }
29
+
30
+ /* Vertical orientation */
31
+ .basefn-button-group--vertical {
32
+ flex-direction: column;
33
+ }
34
+
35
+ .basefn-button-group--vertical > :first-child {
36
+ border-bottom-left-radius: 0;
37
+ border-bottom-right-radius: 0;
38
+ }
39
+
40
+ .basefn-button-group--vertical > :last-child {
41
+ border-top-left-radius: 0;
42
+ border-top-right-radius: 0;
43
+ }
44
+
45
+ .basefn-button-group--vertical > :not(:first-child):not(:last-child) {
46
+ border-radius: 0;
47
+ }
48
+
49
+ .basefn-button-group--vertical > :not(:first-child) {
50
+ margin-top: -1px;
51
+ }
52
+
53
+ /* Ensure proper z-index on hover/focus */
54
+ .basefn-button-group > *:hover,
55
+ .basefn-button-group > *:focus {
56
+ z-index: 1;
57
+ position: relative;
58
+ }
@@ -0,0 +1,33 @@
1
+ %%raw(`import './Basefn__ButtonGroup.css'`)
2
+
3
+ open Xote
4
+
5
+ type orientation = Horizontal | Vertical
6
+
7
+ let orientationToString = (orientation: orientation) => {
8
+ switch orientation {
9
+ | Horizontal => "horizontal"
10
+ | Vertical => "vertical"
11
+ }
12
+ }
13
+
14
+ @jsx.component
15
+ let make = (
16
+ ~orientation: orientation=Horizontal,
17
+ ~className: option<string>=?,
18
+ ~children: Component.node,
19
+ ) => {
20
+ let getClassName = () => {
21
+ let baseClass = "basefn-button-group"
22
+ let orientationClass = " basefn-button-group--" ++ orientationToString(orientation)
23
+ let customClass = switch className {
24
+ | Some(c) => " " ++ c
25
+ | None => ""
26
+ }
27
+ baseClass ++ orientationClass ++ customClass
28
+ }
29
+
30
+ <div class={getClassName()} role="group">
31
+ {children}
32
+ </div>
33
+ }