├── .github └── workflows │ ├── create-version.yml │ └── publish-on-release.yml ├── .gitignore ├── .npmignore ├── README.md ├── assets └── cover.svg ├── bsconfig.json ├── package.json ├── src └── Radix.res └── yarn.lock /.github/workflows/create-version.yml: -------------------------------------------------------------------------------- 1 | name: Create version 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | versionType: 7 | description: Version type 8 | required: true 9 | default: 'patch' 10 | type: choice 11 | options: 12 | - patch 13 | - minor 14 | - major 15 | - premajor 16 | - preminor 17 | - prepatch 18 | - prerelease 19 | 20 | jobs: 21 | create-version: 22 | runs-on: ubuntu-latest 23 | steps: 24 | - uses: actions/checkout@v3 25 | with: 26 | ssh-key: ${{ secrets.ADMIN_SSH_KEY }} 27 | - uses: actions/setup-node@v1 28 | with: 29 | node-version: 16 30 | - run: | 31 | git config user.name rescriptbr-admin 32 | git config user.email rescriptbr@gmail.com 33 | 34 | - name: Generate new version ${{ github.event.inputs.versionType }} 35 | run: | 36 | yarn version --${{ github.event.inputs.versionType }} 37 | 38 | - name: Push the tags 39 | run: git push origin main --tags 40 | -------------------------------------------------------------------------------- /.github/workflows/publish-on-release.yml: -------------------------------------------------------------------------------- 1 | name: Publish package on NPM 2 | 3 | on: 4 | release: 5 | types: [created] 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v3 12 | - uses: actions/setup-node@v2 13 | with: 14 | node-version: 16 15 | - run: yarn 16 | - run: yarn build 17 | 18 | publish-npm: 19 | needs: build 20 | runs-on: ubuntu-latest 21 | steps: 22 | - uses: actions/checkout@v3 23 | - uses: actions/setup-node@v2 24 | with: 25 | node-version: 16 26 | registry-url: https://registry.npmjs.org/ 27 | - run: npm publish --access=public 28 | env: 29 | NODE_AUTH_TOKEN: ${{secrets.ADMIN_NPM_TOKEN}} 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .merlin 3 | .bsb.lock 4 | npm-debug.log 5 | /node_modules/ 6 | src/*.js 7 | lib 8 | package-lock.json 9 | .bs.js 10 | /example/src/*.bs.js 11 | *.bs.js 12 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /node_modules/ 3 | .merlin 4 | *.log 5 | /tests/ 6 | /static/ 7 | /example/ 8 | /assets/ 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |
4 |

5 | 6 | # ReScript Radix UI 7 | 8 | [Radix UI](https://www.radix-ui.com/) bindings for ReScript. 9 | 10 | ## Installation 11 | 12 | 1. Install `@rescriptbr/radix-ui` using npm/yarn: 13 | 14 | ``` 15 | npm install --save @rescriptbr/radix-ui 16 | ``` 17 | 18 | or yarn: 19 | 20 | ``` 21 | yarn add @rescriptbr/radix-ui 22 | ``` 23 | 24 | 2. Add `@rescriptbr/radix-ui` as dependency to your `bsconfig.json`: 25 | 26 | ```json 27 | { 28 | "name": "your-project", 29 | "bs-dependencies": ["@rescriptbr/radix-ui"] 30 | } 31 | ``` 32 | 33 | ## Contributing 34 | 35 | If you'd like to contribute, you can follow the instructions below to get things working locally. 36 | 37 | ### Getting Started 38 | 39 | 1. After cloning the repo, install the dependencies 40 | 41 | ``` 42 | yarn install 43 | ``` 44 | 45 | 2. Build: 46 | 47 | ``` 48 | yarn re:build 49 | ``` 50 | 51 | 3. If you're running the example, in other terminal run: 52 | 53 | ``` 54 | yarn start 55 | ``` 56 | -------------------------------------------------------------------------------- /assets/cover.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /bsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@rescriptbr/radix-ui", 3 | "bsc-flags": ["-bs-super-errors"], 4 | "version": "1.0.0", 5 | "sources": ["src"], 6 | "bs-dependencies": ["@rescript/react"], 7 | "reason": { 8 | "react-jsx": 3 9 | }, 10 | "refmt": 3 11 | } 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@rescriptbr/radix-ui", 3 | "version": "1.3.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "scripts": { 7 | "build": "rescript build -w" 8 | }, 9 | "peerDependencies": { 10 | "@rescript/react": "^0.10.3", 11 | "react": "^17.0.2", 12 | "react-dom": "^17.0.2", 13 | "rescript": "^9.1.4" 14 | }, 15 | "devDependencies": { 16 | "@rescript/react": "^0.10.3", 17 | "react": "^18.2.0", 18 | "react-dom": "^18.2.0", 19 | "rescript": "^9.1.4" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Radix.res: -------------------------------------------------------------------------------- 1 | module Dialog = { 2 | module Root = { 3 | @react.component @module("@radix-ui/react-dialog") 4 | external make: ( 5 | ~children: React.element, 6 | ~onOpenChange: bool => unit=?, 7 | ~_open: bool=?, 8 | ) => React.element = "Root" 9 | } 10 | 11 | module Trigger = { 12 | @react.component @module("@radix-ui/react-dialog") 13 | external make: ( 14 | ~children: React.element, 15 | ~asChild: bool=?, 16 | ~onClick: unit => unit=?, 17 | ) => React.element = "Trigger" 18 | } 19 | 20 | module Portal = { 21 | @react.component @module("@radix-ui/react-dialog") 22 | external make: (~children: React.element) => React.element = "Portal" 23 | } 24 | 25 | module Overlay = { 26 | @react.component @module("@radix-ui/react-dialog") 27 | external make: (~className: string=?) => React.element = "Overlay" 28 | } 29 | 30 | module Content = { 31 | @react.component @module("@radix-ui/react-dialog") 32 | external make: ( 33 | ~asChild: bool=?, 34 | ~className: string=?, 35 | ~children: React.element, 36 | ) => React.element = "Content" 37 | } 38 | 39 | module Title = { 40 | @react.component @module("@radix-ui/react-dialog") 41 | external make: ( 42 | ~children: React.element, 43 | ~className: string=?, 44 | ~asChild: bool=?, 45 | ) => React.element = "Title" 46 | } 47 | 48 | module Description = { 49 | @react.component @module("@radix-ui/react-dialog") 50 | external make: (~children: React.element, ~asChild: bool=?) => React.element = "Description" 51 | } 52 | 53 | module Close = { 54 | @react.component @module("@radix-ui/react-dialog") 55 | external make: (~children: React.element=?, ~asChild: bool=?) => React.element = "Close" 56 | } 57 | } 58 | 59 | module Popover = { 60 | module Root = { 61 | @module("@radix-ui/react-popover") @react.component 62 | external make: ( 63 | ~defaultOpen: bool=?, 64 | ~_open: bool=?, 65 | ~onOpenChange: bool => unit=?, 66 | ~modal: bool=?, 67 | ~children: React.element, 68 | ) => React.element = "Root" 69 | } 70 | 71 | module Trigger = { 72 | @module("@radix-ui/react-popover") @react.component 73 | external make: (~asChild: bool=?, ~children: React.element=?) => React.element = "Trigger" 74 | } 75 | 76 | module Portal = { 77 | @module("@radix-ui/react-popover") @react.component 78 | external make: ( 79 | ~container: 'any=?, 80 | ~className: string=?, 81 | ~asChild: bool=?, 82 | ~forceMount: bool=?, 83 | ~children: React.element=?, 84 | ) => React.element = "Portal" 85 | } 86 | 87 | module Anchor = { 88 | @module("@radix-ui/react-popover") @react.component 89 | external make: (~asChild: bool=?, ~children: React.element=?) => React.element = "Anchor" 90 | } 91 | 92 | module Content = { 93 | type event 94 | @module("@radix-ui/react-popover") @react.component 95 | external make: ( 96 | ~asChild: bool=?, 97 | ~allowPinchZoom: bool=?, 98 | ~onOpenAutoFocus: event => unit=?, 99 | ~onCloseAutoFocus: event => unit=?, 100 | ~onEscapeKeyDown: event => unit=?, 101 | ~onPointerDownOutside: event => unit=?, 102 | ~onFocusOutside: event => unit=?, 103 | ~onInteractOutside: event => unit=?, 104 | ~portalled: bool=?, 105 | ~forceMount: bool=?, 106 | ~side: [#top | #right | #bottom | #left]=?, 107 | ~sideOffset: int=?, 108 | ~align: [#start | #center | #end]=?, 109 | ~alignOffset: int=?, 110 | ~avoidCollisions: bool=?, 111 | ~collisionTolerance: int=?, 112 | ~hideWhenDetached: bool=?, 113 | ~className: string=?, 114 | ~children: React.element, 115 | ) => React.element = "Content" 116 | } 117 | 118 | module Arrow = { 119 | type event 120 | @module("@radix-ui/react-popover") @react.component 121 | external make: ( 122 | ~asChild: bool=?, 123 | ~width: int=?, 124 | ~height: int=?, 125 | ~offset: int, 126 | ~className: string=?, 127 | ) => React.element = "Arrow" 128 | } 129 | 130 | module Close = { 131 | type event 132 | @module("@radix-ui/react-popover") @react.component 133 | external make: ( 134 | ~asChild: bool=?, 135 | ~className: string=?, 136 | ~children: React.element=?, 137 | ) => React.element = "Close" 138 | } 139 | } 140 | 141 | module Switch = { 142 | module Thumb = { 143 | @react.component @module("@radix-ui/react-switch") 144 | external make: (~className: string=?) => React.element = "Thumb" 145 | } 146 | 147 | module Root = { 148 | @react.component @module("@radix-ui/react-switch") 149 | external make: ( 150 | ~className: string=?, 151 | ~defaultCheked: bool=?, 152 | ~checked: bool=?, 153 | ~onCheckedChange: bool => unit=?, 154 | ~disabled: bool=?, 155 | ~required: bool=?, 156 | ~name: string=?, 157 | ~value: string=?, 158 | ~children: React.element, 159 | ) => React.element = "Root" 160 | } 161 | } 162 | 163 | module NavigationMenu = { 164 | module Root = { 165 | @react.component @module("@radix-ui/react-navigation-menu") 166 | external make: ( 167 | ~className: string=?, 168 | ~value: string=?, 169 | ~onValueChange: string => unit=?, 170 | ~dir: [#ltr | #rtl]=?, 171 | ~orientation: [#horizontal | #vertical]=?, 172 | ~children: React.element, 173 | ) => React.element = "Root" 174 | } 175 | 176 | module List = { 177 | @react.component @module("@radix-ui/react-navigation-menu") 178 | external make: ( 179 | ~className: string=?, 180 | ~asChild: bool=?, 181 | ~children: React.element=?, 182 | ) => React.element = "List" 183 | } 184 | 185 | module Item = { 186 | @react.component @module("@radix-ui/react-navigation-menu") 187 | external make: ( 188 | ~className: string=?, 189 | ~asChild: bool=?, 190 | ~value: string=?, 191 | ~children: React.element=?, 192 | ) => React.element = "Item" 193 | } 194 | 195 | module Content = { 196 | @react.component @module("@radix-ui/react-navigation-menu") 197 | external make: ( 198 | ~className: string=?, 199 | ~disableOutsidePointerEvents: bool=?, 200 | ~onEscapeKeyDown: ReactEvent.Keyboard.t => unit=?, 201 | ~onPointerDownOutside: ReactEvent.Pointer.t => unit=?, 202 | ~onFocusOutside: ReactEvent.Focus.t => unit=?, 203 | ~onInteractOutside: 'event => unit=?, 204 | ~forceMount: bool=?, 205 | ~children: React.element=?, 206 | ) => React.element = "Content" 207 | } 208 | 209 | module Trigger = { 210 | @react.component @module("@radix-ui/react-navigation-menu") 211 | external make: ( 212 | ~className: string=?, 213 | ~asChild: bool=?, 214 | ~children: React.element=?, 215 | ) => React.element = "Trigger" 216 | } 217 | 218 | module Link = { 219 | @react.component @module("@radix-ui/react-navigation-menu") 220 | external make: ( 221 | ~className: string=?, 222 | ~asChild: bool=?, 223 | ~active: bool=?, 224 | ~onSelect: ReactEvent.Mouse.t => unit=?, 225 | ~children: React.element, 226 | ) => React.element = "Link" 227 | } 228 | 229 | module Viewport = { 230 | @react.component @module("@radix-ui/react-navigation-menu") 231 | external make: (~className: string=?, ~forceMount: bool=?) => React.element = "Viewport" 232 | } 233 | } 234 | 235 | module Tooltip = { 236 | module Provider = { 237 | @react.component @module("@radix-ui/react-tooltip") 238 | external make: ( 239 | ~children: React.element, 240 | ~delayDuration: float=?, 241 | ~skipDelayDuration: float=?, 242 | ) => React.element = "Provider" 243 | } 244 | 245 | module Root = { 246 | @react.component @module("@radix-ui/react-tooltip") 247 | external make: ( 248 | ~defaultOpen: bool=?, 249 | ~_open: bool=?, 250 | ~onOpenChange: unit => unit=?, 251 | ~delayDuration: float=?, 252 | ~children: React.element, 253 | ) => React.element = "Root" 254 | } 255 | 256 | module Trigger = { 257 | @react.component @module("@radix-ui/react-tooltip") 258 | external make: (~asChild: bool=?, ~children: React.element) => React.element = "Trigger" 259 | } 260 | 261 | module Content = { 262 | @react.component @module("@radix-ui/react-tooltip") 263 | external make: ( 264 | ~children: React.element, 265 | ~asChild: bool=?, 266 | ~ariaLabel: string=?, 267 | ~portalled: bool=?, 268 | ~side: [#top | #right | #left | #bottom]=?, 269 | ~sideOffset: float=?, 270 | ~align: [#start | #center | #end]=?, 271 | ~alignOffset: float=?, 272 | ~avoidCollisions: bool=?, 273 | ~collisionsTolerance: float=?, 274 | ~className: string=?, 275 | ) => React.element = "Content" 276 | } 277 | 278 | module Arrow = { 279 | @react.component @module("@radix-ui/react-tooltip") 280 | external make: ( 281 | ~asChild: bool=?, 282 | ~width: float=?, 283 | ~height: float=?, 284 | ~offset: float=?, 285 | ~className: string=?, 286 | ) => React.element = "Arrow" 287 | } 288 | } 289 | 290 | module Tabs = { 291 | module Root = { 292 | @react.component @module("@radix-ui/react-tabs") 293 | external make: ( 294 | ~className: string=?, 295 | ~children: React.element, 296 | ~asChild: bool=?, 297 | ~defaultValue: string=?, 298 | ~value: string=?, 299 | ~onValueChange: string => unit=?, 300 | ~orientation: [#horizontal | #vertical]=?, 301 | ~dir: [#ltr | #rtl]=?, 302 | ~activationMode: [#automatic | #manual]=?, 303 | ) => React.element = "Root" 304 | } 305 | 306 | module List = { 307 | @react.component @module("@radix-ui/react-tabs") 308 | external make: ( 309 | ~className: string=?, 310 | ~children: React.element, 311 | ~loop: bool=?, 312 | ~asChild: bool=?, 313 | ) => React.element = "List" 314 | } 315 | 316 | module Trigger = { 317 | @react.component @module("@radix-ui/react-tabs") 318 | external make: ( 319 | ~className: string=?, 320 | ~children: React.element, 321 | ~value: string=?, 322 | ~disabled: bool=?, 323 | ~asChild: bool=?, 324 | ) => React.element = "Trigger" 325 | } 326 | 327 | module Content = { 328 | @react.component @module("@radix-ui/react-tabs") 329 | external make: (~children: React.element, ~value: string=?, ~asChild: bool=?) => React.element = 330 | "Content" 331 | } 332 | } 333 | 334 | module Accordion = { 335 | module Root = { 336 | @react.component @module("@radix-ui/react-accordion") 337 | external make: ( 338 | ~className: string=?, 339 | ~children: React.element, 340 | ~_type: [#single | #multiple], 341 | ~value: string=?, 342 | ~collapsible: bool=?, 343 | ~defaultValue: string=?, 344 | ) => React.element = "Root" 345 | } 346 | 347 | module Item = { 348 | @react.component @module("@radix-ui/react-accordion") 349 | external make: ( 350 | ~children: React.element, 351 | ~className: string=?, 352 | ~value: string, 353 | ) => React.element = "Item" 354 | } 355 | 356 | module Header = { 357 | @react.component @module("@radix-ui/react-accordion") 358 | external make: ( 359 | ~children: React.element, 360 | ~asChild: bool=?, 361 | ~className: string=?, 362 | ) => React.element = "Header" 363 | } 364 | 365 | module Trigger = { 366 | @react.component @module("@radix-ui/react-accordion") 367 | external make: ( 368 | ~asChild: bool=?, 369 | ~className: string=?, 370 | ~children: React.element, 371 | ) => React.element = "Trigger" 372 | } 373 | 374 | module Content = { 375 | @react.component @module("@radix-ui/react-accordion") 376 | external make: ( 377 | ~asChild: bool=?, 378 | ~className: string=?, 379 | ~children: React.element, 380 | ) => React.element = "Content" 381 | } 382 | } 383 | 384 | module Checkbox = { 385 | module Root = { 386 | @react.component @module("@radix-ui/react-checkbox") 387 | external make: ( 388 | ~className: string=?, 389 | ~asChild: bool=?, 390 | ~defaultChecked: bool=?, 391 | ~checked: bool, 392 | ~onCheckedChange: bool => unit, 393 | ~disabled: bool=?, 394 | ~required: bool=?, 395 | ~name: string=?, 396 | ~value: string=?, 397 | ~children: React.element, 398 | ) => React.element = "Root" 399 | } 400 | module Indicator = { 401 | @react.component @module("@radix-ui/react-checkbox") 402 | external make: ( 403 | ~className: string=?, 404 | ~asChild: bool=?, 405 | ~fourceMount: bool=?, 406 | ~children: React.element=?, 407 | ) => React.element = "Indicator" 408 | } 409 | } 410 | 411 | module Collapsible = { 412 | module Root = { 413 | @module("@radix-ui/react-collapsible") @react.component 414 | external make: ( 415 | ~children: React.element=?, 416 | ~_open: bool=?, 417 | ~onOpenChange: bool => unit=?, 418 | ~disabled: bool=?, 419 | ~asChild: bool=?, 420 | ~className: string=?, 421 | ~defaultOpen: bool=?, 422 | ) => React.element = "Root" 423 | } 424 | 425 | module Trigger = { 426 | @module("@radix-ui/react-collapsible") @react.component 427 | external make: ( 428 | ~children: React.element=?, 429 | ~asChild: bool=?, 430 | ~className: string=?, 431 | ) => React.element = "Trigger" 432 | } 433 | 434 | module Content = { 435 | @module("@radix-ui/react-collapsible") @react.component 436 | external make: ( 437 | ~children: React.element=?, 438 | ~forceMount: bool=?, 439 | ~className: string=?, 440 | ) => React.element = "Content" 441 | } 442 | } 443 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@rescript/react@^0.10.3": 6 | version "0.10.3" 7 | resolved "https://registry.yarnpkg.com/@rescript/react/-/react-0.10.3.tgz#a2a8bed6b017940ec26c2154764b350f50348889" 8 | integrity sha512-Lf9rzrR3bQPKJjOK3PBRa/B3xrJ7CqQ1HYr9VHPVxJidarIJJFZBhj0Dg1uZURX+Wg/xiP0PHFxXmdj2bK8Vxw== 9 | 10 | "js-tokens@^3.0.0 || ^4.0.0": 11 | version "4.0.0" 12 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" 13 | integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== 14 | 15 | loose-envify@^1.1.0: 16 | version "1.4.0" 17 | resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" 18 | integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== 19 | dependencies: 20 | js-tokens "^3.0.0 || ^4.0.0" 21 | 22 | react-dom@^18.2.0: 23 | version "18.2.0" 24 | resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" 25 | integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== 26 | dependencies: 27 | loose-envify "^1.1.0" 28 | scheduler "^0.23.0" 29 | 30 | react@^18.2.0: 31 | version "18.2.0" 32 | resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" 33 | integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== 34 | dependencies: 35 | loose-envify "^1.1.0" 36 | 37 | rescript@^9.1.4: 38 | version "9.1.4" 39 | resolved "https://registry.yarnpkg.com/rescript/-/rescript-9.1.4.tgz#1eb126f98d6c16942c0bf0df67c050198e580515" 40 | integrity sha512-aXANK4IqecJzdnDpJUsU6pxMViCR5ogAxzuqS0mOr8TloMnzAjJFu63fjD6LCkWrKAhlMkFFzQvVQYaAaVkFXw== 41 | 42 | scheduler@^0.23.0: 43 | version "0.23.0" 44 | resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" 45 | integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== 46 | dependencies: 47 | loose-envify "^1.1.0" 48 | --------------------------------------------------------------------------------