Repository: rescriptbr/ancestor
Branch: main
Commit: a1c8f4a18848
Files: 140
Total size: 211.7 KB
Directory structure:
gitextract_e4nemrkr/
├── .github/
│ └── workflows/
│ ├── core-tests.yml
│ ├── create-version.yml
│ ├── css-tests.yml
│ └── npm-publish.yml
├── .gitignore
├── .nvmrc
├── .tool-versions
├── README.md
├── netlify.toml
├── package.json
├── packages/
│ ├── bindings/
│ │ ├── bsconfig.json
│ │ ├── package.json
│ │ └── src/
│ │ ├── Emotion.res
│ │ ├── ReactTestRenderer.res
│ │ ├── Storybook.res
│ │ └── storybook.js
│ ├── cli/
│ │ ├── ancestor.config.js
│ │ ├── bsconfig.json
│ │ ├── lib/
│ │ │ └── bs/
│ │ │ ├── .bsbuild
│ │ │ ├── .bsdeps
│ │ │ ├── .ninja_log
│ │ │ ├── .sourcedirs.json
│ │ │ ├── build.ninja
│ │ │ ├── install.ninja
│ │ │ └── src/
│ │ │ ├── ConfigParser.ast
│ │ │ ├── ConfigParser.d
│ │ │ ├── Main.ast
│ │ │ └── Main.d
│ │ ├── package.json
│ │ └── src/
│ │ ├── ConfigParser.res
│ │ └── Main.res
│ ├── core/
│ │ ├── .npmignore
│ │ ├── .storybook/
│ │ │ ├── main.js
│ │ │ ├── preview-head.html
│ │ │ └── preview.js
│ │ ├── __tests__/
│ │ │ ├── Ancestor_Box_Test.res
│ │ │ ├── Ancestor_Grid_Test.res
│ │ │ ├── Ancestor_Hidden_Test.res
│ │ │ ├── Ancestor_ResponsiveValueHook_Test.res
│ │ │ ├── Ancestor_Stack_Test.res
│ │ │ └── __snapshots__/
│ │ │ ├── Ancestor_Box_Test.bs.js.snap
│ │ │ ├── Ancestor_Grid_Test.bs.js.snap
│ │ │ ├── Ancestor_Hidden_Test.bs.js.snap
│ │ │ └── Ancestor_Stack_Test.bs.js.snap
│ │ ├── bsconfig.json
│ │ ├── jest.config.js
│ │ ├── package.json
│ │ ├── scripts/
│ │ │ └── AddProps.res
│ │ └── src/
│ │ ├── Ancestor.res
│ │ ├── _helpers_/
│ │ │ └── Ancestor_Helpers.res
│ │ ├── bindings/
│ │ │ ├── Ancestor_React.res
│ │ │ └── Ancestor_TestingLibrary.res
│ │ ├── components/
│ │ │ ├── base/
│ │ │ │ ├── Ancestor_Base.res
│ │ │ │ └── Ancestor_Base_Stories.res
│ │ │ ├── box/
│ │ │ │ ├── Ancestor_Box.res
│ │ │ │ └── Ancestor_Box_Stories.res
│ │ │ ├── grid/
│ │ │ │ ├── Ancestor_Grid.res
│ │ │ │ └── Ancestor_Grid_Stories.res
│ │ │ ├── hidden/
│ │ │ │ ├── Ancestor_Hidden.res
│ │ │ │ └── Ancestor_Hidden_Stories.res
│ │ │ └── stack/
│ │ │ ├── Ancestor_Stack.res
│ │ │ └── Ancestor_Stack_Stories.res
│ │ ├── core/
│ │ │ ├── Ancestor_Config.res
│ │ │ ├── Ancestor_Core.res
│ │ │ └── Ancestor_Styles.res
│ │ └── hooks/
│ │ ├── Ancestor_ResponsiveValueHook.res
│ │ └── Ancestor_ResponsiveValueHook_Stories.res
│ ├── css/
│ │ ├── .npmignore
│ │ ├── .storybook/
│ │ │ ├── main.js
│ │ │ ├── preview-head.html
│ │ │ └── preview.js
│ │ ├── __tests__/
│ │ │ ├── AncestorCss_Custom.res
│ │ │ ├── AncestorCss_Test.res
│ │ │ └── __snapshots__/
│ │ │ └── AncestorCss_Test.bs.js.snap
│ │ ├── bsconfig.json
│ │ ├── jest.config.js
│ │ ├── package.json
│ │ ├── spec.md
│ │ └── src/
│ │ ├── AncestorCss.res
│ │ ├── AncestorCss_Config.res
│ │ ├── AncestorCss_Context.res
│ │ ├── AncestorCss_Stories.res
│ │ └── AncestorCss_WrappedTypes.res
│ └── ui/
│ ├── .storybook/
│ │ ├── main.js
│ │ ├── preview-head.html
│ │ └── preview.js
│ ├── bsconfig.json
│ ├── package.json
│ └── src/
│ ├── AncestorUI.res
│ ├── Theme.res
│ ├── components/
│ │ └── button/
│ │ ├── Button.res
│ │ └── ButtonTokens.res
│ └── lib/
│ └── AncestorCore.res
└── website/
├── .gitignore
├── .prettierignore
├── .prettierrc
├── README.md
├── babel.config.js
├── bsconfig.json
├── docs/
│ ├── _components/
│ │ └── Placeholder.res
│ ├── _helpers/
│ │ ├── Emotion.res
│ │ ├── Helpers.res
│ │ ├── Theme.res
│ │ └── index.js
│ ├── api/
│ │ ├── base.md
│ │ ├── box.mdx
│ │ ├── examples/
│ │ │ ├── FirstBaseExample.res
│ │ │ ├── FirstBoxExample.res
│ │ │ ├── FirstGridExample.res
│ │ │ ├── FirstHiddenExample.res
│ │ │ ├── FirstStackExample.res
│ │ │ └── SecondStackExample.res
│ │ ├── grid.mdx
│ │ ├── hidden.md
│ │ └── stack.md
│ ├── customization/
│ │ ├── Customization_Breakpoints1.res
│ │ ├── Customization_Colors1.res
│ │ ├── Customization_Radius1.res
│ │ ├── Customization_Spacing1.res
│ │ ├── Customization_Spacing2.res
│ │ ├── Customization_Spacing3.res
│ │ ├── Customization_Spacing4.res
│ │ ├── Customization_ZIndex1.res
│ │ └── customization.md
│ ├── getting-started.md
│ ├── intro.md
│ ├── system-props.md
│ └── use-responsive-value/
│ ├── ResponsiveValueExample.res
│ └── use-responsive-value.md
├── docusaurus.config.js
├── package.json
├── sidebars.js
├── src/
│ ├── bindings/
│ │ └── Docusaurus.res
│ ├── css/
│ │ └── app.css
│ ├── helpers/
│ │ └── Render.res
│ └── pages/
│ ├── Home/
│ │ ├── Home.res
│ │ └── home.module.css
│ ├── index.js
│ └── markdown-page.md
└── static/
└── .nojekyll
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/workflows/core-tests.yml
================================================
name: Core tests
on:
push:
paths:
- packages/core/**
pull_request:
paths:
- packages/core/**
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: 18
- name: Install dependencies
run: yarn
- name: Run the compiler
run: yarn --cwd packages/core rescript build
- name: Run the tests
run: yarn --cwd packages/core test
================================================
FILE: .github/workflows/create-version.yml
================================================
name: Create version
on:
workflow_dispatch:
inputs:
packageName:
description: Package name
required: true
default: "core"
type: choice
options:
- core
- ui
- css
- bindings
versionType:
description: Version type
required: true
default: "patch"
type: choice
options:
- patch
- minor
- major
- premajor
- preminor
- prepatch
- prerelease
jobs:
create-version:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
ssh-key: ${{ secrets.ADMIN_SSH_KEY }}
- uses: actions/setup-node@v1
with:
node-version: 16
- run: |
git config user.name rescriptbr-admin
git config user.email rescriptbr@gmail.com
- name: Generate new version ${{ github.event.inputs.versionType }}
run: |
yarn config set version-tag-prefix "@ancestor-ui/${{ github.event.inputs.packageName }}@"
cd packages/${{ github.event.inputs.packageName }}
yarn version --${{ github.event.inputs.versionType }}
- name: Push the tags
run: git push origin main --tags
================================================
FILE: .github/workflows/css-tests.yml
================================================
name: CSS tests
on:
push:
paths:
- packages/css/**
pull_request:
paths:
- packages/css/**
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: 18
- name: Install dependencies
run: yarn
- name: Run the compiler
run: yarn --cwd packages/css rescript build
- name: Run the tests
run: yarn --cwd packages/css test
================================================
FILE: .github/workflows/npm-publish.yml
================================================
name: Publish package on NPM
on:
workflow_dispatch:
inputs:
packageName:
description: Package name
required: true
default: "core"
type: choice
options:
- core
- ui
- css
- bindings
jobs:
publish-npm:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v2
with:
node-version: 16
registry-url: https://registry.npmjs.org/
- run: cd packages/${{ github.event.inputs.packageName }} && npm publish --access=public
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
================================================
FILE: .gitignore
================================================
*.exe
*.obj
*.out
*.compile
*.native
*.byte
*.cmo
*.annot
*.cmi
*.cmx
*.cmt
*.cmti
*.cma
*.a
*.cmxa
*.obj
*~
*.annot
*.cmj
*.bak
lib/bs
*.mlast
*.mliast
.vscode
.merlin
.bsb.lock
/node_modules/
*.bs.js
packages/core/lib/
packages/ui/lib/
packages/bindings/lib/
packages/css/lib/
packages/**/node_modules/
/website/lib/
/website/node_modules/
.DS_STORE
================================================
FILE: .nvmrc
================================================
v18.0.0
================================================
FILE: .tool-versions
================================================
nodejs 16.20.0
================================================
FILE: README.md
================================================
> ⚠️ **DISCLAIMER**: Considering the recent changes in the use of CSS in JS with runtime and also the maintenance and adaptation effort of this project to align with the direction the ecosystem is taking in the use of CSS in JS, especially with the advent of RSC and frameworks like Remix and Next, this repository is no longer maintained. Furthermore, there are excellent solid options in the JS ecosystem such as Chakra UI, Panda CSS, and Tailwind that satisfactorily meet requirements and work well with ReScript through bindings.
Docs //
Getting Started //
ReScript Brazil Community
# Introduction
**Ancestor** is a suite of components that works as layout primitives to develop high-quality
web apps, design systems, and style guides focused on responsiveness.
## What and Why?
Every front-end project that is using libraries based on components like [React](https://reactjs.org), faces the same situation:
**Choose or develop a UI library to develop the interfaces.**
In some cases, you can use libraries like [Chakra UI](https://chakra-ui.com/), [Material UI](https://material-ui.com/pt/), or
[Ant Design](https://material-ui.com/pt/) that delivers a set of styled components (grids, buttons, inputs, selects, etc)
and a lot of other utility functions and components for your web app.
However, in some cases, the team needs to create its own design system or style guide with a design language, colors, fonts, buttons, inputs
and other specifications created by a design team. In this case, the usage of a library like Material UI or Chakra UI might
not be the best choice, because depends on a lot of customizations or changes to adapt the library to the design specification.
It was the reason that we created Ancestor: **to act as a foundation for your project or design system.**
## Features
### Unstyled 💀
Different from popular libraries like Material UI, we don't deliver styled components with colors, fonts, borders, etc.
All Ancestor's components are **layout primitives** with support to a lot of CSS properties like padding, margin, height, width, etc.
### Responsiveness 💡
All properties from Ancestor's components are responsive, which makes it easy to develop interfaces that need to support multiple devices.
Through the **breakpoints** defined by the library, you can change the appearance of a component in a specific device or screen size.
### Consistent design 🎨
We don't deliver styled components, but we care about design consistency, especially when dealing with spacing, borders, etc.
### Customizable ⚙️
All properties from Ancestor's components and parameters are customizable:
Breakpoints, spacing, radius, grid columns, etc which makes it easy to customize and adapt Ancestor to your design system or style guide.
## Installation
> ⚠️ **DISCLAIMER**: We're working on a new version of Ancestor bringing a complete set of UI tools for ReScript. The most stable version is @rescriptbr/ancestor@0.0.8 and you can install by following the instructions below. Don't forget to install the most stable version, there are unstable pre-release versions that might not work as expected since they're pre-releases.
First off, install **Ancestor** using npm/yarn:
```sh title="Terminal"
yarn add @rescriptbr/ancestor@0.8.0
```
If you want to use the default setup, you need to install [Emotion](https://emotion.sh).
```sh title="Terminal"
yarn add @emotion/css
```
Add the package to `bs-dependencies` in your `bsconfig.json`:
```json title="bsconfig.json"
{
"bs-dependencies": [
"@rescript/react",
"@rescriptbr/ancestor"
]
}
```
## Basic usage
```rescript
open Ancestor.Default
@react.component
let make = () => {
#pct)]>
#rem), #md(20.0->#rem)]
>
{"A place to share knowledge"->React.string}
{"Where good ideas find you."->React.string}
#rem)]
left=[#xs(-5.0->#rem)]
>
....
}
```
_Example from [ReScript Conduit](https://github.com/rescriptbr/rescript-conduit/blob/master/src/pages/Signin/Signin.res)_
## Documentation
Check out the [official documentation](https://ancestor.netlify.app).
## License
MIT
================================================
FILE: netlify.toml
================================================
[build]
ignore = "git diff --quiet $CACHED_COMMIT_REF $COMMIT_REF website/"
================================================
FILE: package.json
================================================
{
"name": "ancestor",
"private": true,
"version": "0.1.0",
"main": "index.js",
"license": "MIT",
"workspaces": [
"packages/*",
"website"
],
"scripts": {
"core": "yarn workspace @ancestor-ui/core",
"core:compile": "yarn core build",
"core:test": "yarn core test",
"website": "yarn workspace website",
"docs:docusaurus": "yarn website docusaurus",
"docs:compile": "yarn website build -w",
"docs:start": "yarn website docusaurus start",
"docs:build": "yarn website build",
"docs:clear": "yarn website docusaurus clear"
},
"devDependencies": {},
"peerDependencies": {},
"dependencies": {}
}
================================================
FILE: packages/bindings/bsconfig.json
================================================
{
"name": "@ancestor-ui/bindings",
"namespace": false,
"version": "0.0.1",
"sources": [
{
"dir": "src",
"subdirs": true
}
],
"package-specs": [
{
"module": "commonjs",
"in-source": true
}
],
"reason": {
"react-jsx": 3
},
"suffix": ".bs.js",
"bs-dependencies": ["@rescript/react"],
"bs-dev-dependencies": [],
"ppx-flags": []
}
================================================
FILE: packages/bindings/package.json
================================================
{
"name": "@ancestor-ui/bindings",
"version": "0.1.0",
"main": "index.js",
"license": "MIT",
"devDependencies": {
"@emotion/css": "11.10.0",
"@rescript/react": "0.11.0-rc.3",
"react": "18.2.0",
"react-dom": "18.2.0",
"rescript": "10.1.0"
}
}
================================================
FILE: packages/bindings/src/Emotion.res
================================================
@module("@emotion/css") external keyframes: {..} => string = "keyframes"
@module("@emotion/css") external cx: array => string = "cx"
@module("@emotion/css") external compose: (string, string) => string = "css"
@module("@emotion/css") external injectGlobal: {..} => unit = "injectGlobal"
@module("@emotion/css") external injectGlobalRaw: string => unit = "injectGlobal"
@module("@emotion/css") external css: {..} => string = "css"
@module("@emotion/css") external rawCss: string => string = "css"
================================================
FILE: packages/bindings/src/ReactTestRenderer.res
================================================
type rendered
@send external toJSON: rendered => Js.Json.t = "toJSON"
@module("react-test-renderer") external create: React.element => rendered = "create"
================================================
FILE: packages/bindings/src/Storybook.res
================================================
let story = (~title, ~component=?, ~argTypes=?, ~excludeStories=[], ()) => {
let ignoredStories = switch excludeStories {
| [] => "default"
| stories => "default|"->Js.String2.concat(stories->Js.Array2.joinWith("|"))
}
{
"title": title,
"excludeStories": Js.Re.fromString(ignoredStories),
"component": component,
"argTypes": argTypes,
}
}
@module("./storybook.js") external addArgTypes: ('props => React.element, {..}) => unit = "default"
================================================
FILE: packages/bindings/src/storybook.js
================================================
export default (fn, args) => (fn.argTypes = args);
================================================
FILE: packages/cli/ancestor.config.js
================================================
module.exports = {
fileName: "AncestorCustom",
breakpoints: {
xs: 0,
sm: 400,
md: 720,
},
};
================================================
FILE: packages/cli/bsconfig.json
================================================
{
"name": "@ancestor-ui/cli",
"sources": [
{
"dir": "src",
"subdirs": true
}
],
"package-specs": [
{
"module": "commonjs",
"in-source": true
}
],
"reason": {
"react-jsx": 3
},
"suffix": ".bs.js",
"bs-dependencies": ["rescript-nodejs", "@rescript/react", "rescript-ink"],
"bs-dev-dependencies": [],
"ppx-flags": []
}
================================================
FILE: packages/cli/lib/bs/.bsbuild
================================================
2
Main
ConfigParser
src
1
0
================================================
FILE: packages/cli/lib/bs/.bsdeps
================================================
10.1.2
/Users/marcos/Projects/ancestor/packages/cli
0
bsconfig.json 0x1.8f93df04p+30
src 0x1.8f93ef8cp+30
===
/Users/marcos/Projects/ancestor/packages/cli/node_modules/rescript/darwinarm64/rescript.exe 0x1.8f93be64p+30
================================================
FILE: packages/cli/lib/bs/.ninja_log
================================================
# ninja log v6
27 45 1675951075170856649 ../../src/ConfigParser.bs.js 737f6854d89ba736
27 45 1675951075170856649 src/ConfigParser.cmj 737f6854d89ba736
20 27 1675970348862273652 src/ConfigParser.d af717c3ce1502d2c
27 45 1675951075170856649 src/ConfigParser.cmi 737f6854d89ba736
0 12 1675951357505975876 src/Main.ast f997a5986aa1d877
45 59 1675970348884749639 ../../src/Main.bs.js 99675fd5a8e452a6
45 59 1675970348884749639 src/Main.cmj 99675fd5a8e452a6
45 59 1675970348884749639 src/Main.cmi 99675fd5a8e452a6
0 20 1675970348862273652 src/ConfigParser.ast bae8a1de5784cbf6
12 18 1675951357505975876 src/Main.d 4373da1273a138
0 11 1675970352651145388 src/ConfigParser.ast bae8a1de5784cbf6
12 16 1675970352651145388 src/ConfigParser.d af717c3ce1502d2c
16 28 1675951075170856649 src/ConfigParser.cmj 737f6854d89ba736
16 28 1675951075170856649 src/ConfigParser.cmi 737f6854d89ba736
16 28 1675951075170856649 ../../src/ConfigParser.bs.js 737f6854d89ba736
28 38 1675970352666342028 src/Main.cmj 99675fd5a8e452a6
28 38 1675970352666342028 src/Main.cmi 99675fd5a8e452a6
28 38 1675970352666342028 ../../src/Main.bs.js 99675fd5a8e452a6
0 12 1675970355760331644 src/ConfigParser.ast bae8a1de5784cbf6
12 17 1675970355760331644 src/ConfigParser.d af717c3ce1502d2c
17 29 1675951075170856649 src/ConfigParser.cmj 737f6854d89ba736
17 29 1675951075170856649 src/ConfigParser.cmi 737f6854d89ba736
17 29 1675951075170856649 ../../src/ConfigParser.bs.js 737f6854d89ba736
29 40 1675970355776584394 src/Main.cmj 99675fd5a8e452a6
29 40 1675970355776584394 src/Main.cmi 99675fd5a8e452a6
29 40 1675970355776584394 ../../src/Main.bs.js 99675fd5a8e452a6
1 21 1675970404045653271 src/ConfigParser.ast bae8a1de5784cbf6
21 28 1675970404045653271 src/ConfigParser.d af717c3ce1502d2c
28 44 1675970404070522845 src/ConfigParser.cmj 737f6854d89ba736
28 44 1675970404070522845 src/ConfigParser.cmi 737f6854d89ba736
28 44 1675970404070522845 ../../src/ConfigParser.bs.js 737f6854d89ba736
45 58 1675970404070287765 src/Main.cmj 99675fd5a8e452a6
45 58 1675970404070287765 src/Main.cmi 99675fd5a8e452a6
45 58 1675970404070287765 ../../src/Main.bs.js 99675fd5a8e452a6
0 11 1675970412180853146 src/ConfigParser.ast bae8a1de5784cbf6
11 16 1675970412180853146 src/ConfigParser.d af717c3ce1502d2c
16 28 1675970412180853146 src/ConfigParser.cmj 737f6854d89ba736
16 28 1675970412180853146 src/ConfigParser.cmi 737f6854d89ba736
16 28 1675970412180853146 ../../src/ConfigParser.bs.js 737f6854d89ba736
28 38 1675970412196298782 src/Main.cmj 99675fd5a8e452a6
28 38 1675970412196298782 src/Main.cmi 99675fd5a8e452a6
28 38 1675970412196298782 ../../src/Main.bs.js 99675fd5a8e452a6
1 11 1675970451401505656 src/ConfigParser.ast bae8a1de5784cbf6
11 16 1675970451401505656 src/ConfigParser.d af717c3ce1502d2c
0 20 1675970484485915455 src/ConfigParser.ast bae8a1de5784cbf6
20 27 1675970484485915455 src/ConfigParser.d af717c3ce1502d2c
27 42 1675951075170856649 src/ConfigParser.cmj 737f6854d89ba736
27 42 1675951075170856649 src/ConfigParser.cmi 737f6854d89ba736
27 42 1675951075170856649 ../../src/ConfigParser.bs.js 737f6854d89ba736
42 54 1675970484507216793 src/Main.cmj 99675fd5a8e452a6
42 54 1675970484507216793 src/Main.cmi 99675fd5a8e452a6
42 54 1675970484507216793 ../../src/Main.bs.js 99675fd5a8e452a6
0 13 1675970492542645873 src/ConfigParser.ast bae8a1de5784cbf6
13 19 1675970492542645873 src/ConfigParser.d af717c3ce1502d2c
19 31 1675970492542645873 src/ConfigParser.cmj 737f6854d89ba736
19 31 1675970492542645873 src/ConfigParser.cmi 737f6854d89ba736
19 31 1675970492542645873 ../../src/ConfigParser.bs.js 737f6854d89ba736
31 42 1675970492559499488 src/Main.cmj 99675fd5a8e452a6
31 42 1675970492559499488 src/Main.cmi 99675fd5a8e452a6
31 42 1675970492559499488 ../../src/Main.bs.js 99675fd5a8e452a6
0 43 1675970538879712033 src/ConfigParser.ast bae8a1de5784cbf6
43 50 1675970538879712033 src/ConfigParser.d af717c3ce1502d2c
50 63 1675970538879712033 src/ConfigParser.cmj 737f6854d89ba736
50 63 1675970538879712033 src/ConfigParser.cmi 737f6854d89ba736
50 63 1675970538879712033 ../../src/ConfigParser.bs.js 737f6854d89ba736
0 36 1676028648639373678 src/ConfigParser.ast bae8a1de5784cbf6
36 47 1676028648639373678 src/ConfigParser.d af717c3ce1502d2c
47 60 1676028648639373678 src/ConfigParser.cmj 737f6854d89ba736
47 60 1676028648639373678 src/ConfigParser.cmi 737f6854d89ba736
47 60 1676028648639373678 ../../src/ConfigParser.bs.js 737f6854d89ba736
================================================
FILE: packages/cli/lib/bs/.sourcedirs.json
================================================
{ "dirs" : [ "src" ] , "pkgs" : [ [ "rescript-ink" , "/Users/marcos/Projects/ancestor/packages/cli/node_modules/rescript-ink" ] , [ "rescript-nodejs" , "/Users/marcos/Projects/ancestor/node_modules/rescript-nodejs" ] , [ "@rescript/react" , "/Users/marcos/Projects/ancestor/node_modules/@rescript/react" ] ] , "generated" : [] }
================================================
FILE: packages/cli/lib/bs/build.ninja
================================================
rescript = 1
g_finger := /Users/marcos/Projects/ancestor/node_modules/rescript-nodejs/lib/ocaml/install.stamp
g_finger := /Users/marcos/Projects/ancestor/node_modules/@rescript/react/lib/ocaml/install.stamp
g_finger := /Users/marcos/Projects/ancestor/packages/cli/node_modules/rescript-ink/lib/ocaml/install.stamp
rule astj
command = /Users/marcos/Projects/ancestor/packages/cli/node_modules/rescript/darwinarm64/bsc.exe -bs-v 10.1.2 -bs-jsx 3 -absname -bs-ast -o $out $i
o src/Main.ast : astj ../../src/Main.res
rule deps
command = /Users/marcos/Projects/ancestor/packages/cli/node_modules/rescript/darwinarm64/bsb_helper.exe -hash b4d1b30a18559a085b0eb9325c0a99d3 $in
restat = 1
o src/Main.d : deps src/Main.ast
rule mij
command = /Users/marcos/Projects/ancestor/packages/cli/node_modules/rescript/darwinarm64/bsc.exe -I src -I /Users/marcos/Projects/ancestor/node_modules/rescript-nodejs/lib/ocaml -I /Users/marcos/Projects/ancestor/node_modules/@rescript/react/lib/ocaml -I /Users/marcos/Projects/ancestor/packages/cli/node_modules/rescript-ink/lib/ocaml -bs-package-name @ancestor-ui/cli -bs-package-output commonjs:$in_d:.bs.js -bs-v $g_finger $i
dyndep = 1
restat = 1
o src/Main.cmj src/Main.cmi ../../src/Main.bs.js : mij src/Main.ast
o src/ConfigParser.ast : astj ../../src/ConfigParser.res
o src/ConfigParser.d : deps src/ConfigParser.ast
o src/ConfigParser.cmj src/ConfigParser.cmi ../../src/ConfigParser.bs.js : mij src/ConfigParser.ast
================================================
FILE: packages/cli/lib/bs/install.ninja
================================================
rescript = 1
rule cp
command = cp $i $out
rule touch
command = touch $out
o Main.cmi : cp ../bs/src/Main.cmi
o Main.cmj : cp ../bs/src/Main.cmj
o Main.cmt : cp ../bs/src/Main.cmt
o Main.res : cp ../../src/Main.res
o ConfigParser.cmi : cp ../bs/src/ConfigParser.cmi
o ConfigParser.cmj : cp ../bs/src/ConfigParser.cmj
o ConfigParser.cmt : cp ../bs/src/ConfigParser.cmt
o ConfigParser.res : cp ../../src/ConfigParser.res
build install.stamp : touch Main.cmi Main.cmj ConfigParser.cmi ConfigParser.cmj
================================================
FILE: packages/cli/lib/bs/src/ConfigParser.d
================================================
================================================
FILE: packages/cli/lib/bs/src/Main.d
================================================
src/Main.cmj : src/ConfigParser.cmj src/ConfigParser.cmi
================================================
FILE: packages/cli/package.json
================================================
{
"name": "@ancestor-ui/cli",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"dependencies": {
"@rescript/react": "0.10.3",
"rescript": "10.1.2",
"rescript-ink": "1.3.0",
"rescript-nodejs": "14.3.1"
}
}
================================================
FILE: packages/cli/src/ConfigParser.res
================================================
module Classifier = {
type any
type tagged<'keyValue> = Object(array<(string, 'keyValue)>) | Unknown
let objectFromAny = value => {
let value: Js.Dict.t<'value> = Obj.magic(value)
Object(value->Js.Dict.entries)
}
let classify = any => {
let typeof = Js.typeof(any->Obj.magic)
switch typeof {
| "object" => objectFromAny(any)
| _ => Unknown
}
}
}
type configValue
type configRaw = {breakpoints?: configValue}
module Breakpoints = {
type breakpointItem = {key: string, value: int}
type t = array
let itemsFromEntries = entries => entries->Js.Array2.map(((key, value)) => {key, value})
let fromRaw = value =>
value
->Belt.Option.map(Classifier.classify)
->Belt.Option.flatMap(v =>
switch v {
| Object(entries) => Some(itemsFromEntries(entries))
| _ => None
}
)
}
type config = {breakpoints?: Breakpoints.t}
let parseConfig = (configRaw: configRaw): config => {
breakpoints: ?configRaw.breakpoints->Breakpoints.fromRaw,
}
let configFilePath = Node.Path.join([Node.Process.cwd(), `ancestor.config.js`])
@val external _require: string => configRaw = "require"
let getConfig = () => {
_require(configFilePath)->parseConfig->Js.log
}
================================================
FILE: packages/cli/src/Main.res
================================================
open Ink
module App = {
@react.component
let make = () => {
React.useEffect0(() => {
ConfigParser.getConfig()
None
})
{"Testing..."->React.string}
}
}
let {waitUntilExit} = render( , ~exitOnCtrlC=true, ())
waitUntilExit()->ignore
================================================
FILE: packages/core/.npmignore
================================================
*_Stories.res
*_Test.res
__tests__/
scripts/
src/_helpers_/
**/__snapshots__/
.storybook
================================================
FILE: packages/core/.storybook/main.js
================================================
module.exports = {
"stories": [
"../src/**/*_Stories.bs.js"
],
"addons": [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions"
],
"framework": "@storybook/react"
}
================================================
FILE: packages/core/.storybook/preview-head.html
================================================
================================================
FILE: packages/core/.storybook/preview.js
================================================
export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
}
================================================
FILE: packages/core/__tests__/Ancestor_Box_Test.res
================================================
open Jest
open Expect
open Ancestor
module Renderer = ReactTestRenderer
describe("Box", () => {
test("should render with columns correctly", () => {
expect(
Renderer.create(
,
)->Renderer.toJSON,
)->toMatchSnapshot
})
test("should render without columns correctly", () => {
expect(
Renderer.create(
,
)->Renderer.toJSON,
)->toMatchSnapshot
})
})
================================================
FILE: packages/core/__tests__/Ancestor_Grid_Test.res
================================================
open Jest
open Expect
open Ancestor
module Renderer = ReactTestRenderer
describe("Grid", () => {
test("should with spacing render correctly", () => {
expect(
Renderer.create(
{"Column 1"->React.string}
{"Column 2"->React.string}
{"Column 3"->React.string}
{"Column 4"->React.string}
,
)->Renderer.toJSON,
)->toMatchSnapshot
})
test("should without spacing render correctly", () => {
expect(
Renderer.create(
{"Column 1"->React.string}
{"Column 2"->React.string}
{"Column 3"->React.string}
{"Column 4"->React.string}
,
)->Renderer.toJSON,
)->toMatchSnapshot
})
})
================================================
FILE: packages/core/__tests__/Ancestor_Hidden_Test.res
================================================
open Jest
open Expect
open Ancestor
module Renderer = ReactTestRenderer
describe("Hidden", () => {
test("should visually hide elements correctly", () => {
expect(
Renderer.create(
,
)->Renderer.toJSON,
)->toMatchSnapshot
})
})
================================================
FILE: packages/core/__tests__/Ancestor_ResponsiveValueHook_Test.res
================================================
open Jest
open Expect
open Ancestor_TestingLibrary
/**
* Helper function to resize the window.
*/
%%raw(`
window.resizeTo = function resizeTo(width) {
Object.assign(this, {
innerWidth: width,
outerWidth: width,
}).dispatchEvent(new this.Event('resize'))
}
`)
@val external window: Dom.window = "window"
@send external resizeTo: (Dom.window, int) => unit = "resizeTo"
describe("ResponsiveValueHook", () => {
describe(".useResponsiveValue(...)", () => {
test(
"should returns the responsive value correctly",
() => {
let {result} = renderHook(
() => Ancestor.useResponsiveValue("Default", {xs: "Mobile", md: "Tablet"}),
)
expect(result.current)->toBe("Tablet")
act((. ()) => window->resizeTo(320))
expect(result.current)->toBe("Mobile")
},
)
})
})
================================================
FILE: packages/core/__tests__/Ancestor_Stack_Test.res
================================================
open Jest
open Expect
open Ancestor
module Renderer = ReactTestRenderer
describe("Stack", () => {
test("should render correctly", () => {
expect(
Renderer.create(
,
)->Renderer.toJSON,
)->toMatchSnapshot
})
test("should render with dividers correctly", () => {
let placeholder = {`Placeholder`->React.string}
let divider = {`Divider`->React.string}
expect(
Renderer.create(
placeholder
placeholder
,
)->Renderer.toJSON,
)->toMatchSnapshot
})
})
================================================
FILE: packages/core/__tests__/__snapshots__/Ancestor_Box_Test.bs.js.snap
================================================
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Box should render with columns correctly 1`] = `
@media (min-width:0px) {
.emotion-0 {
-webkit-flex-basis: 50%;
-ms-flex-preferred-size: 50%;
flex-basis: 50%;
}
}
@media (min-width:920px) {
.emotion-0 {
-webkit-flex-basis: 100%;
-ms-flex-preferred-size: 100%;
flex-basis: 100%;
}
}
@media (min-width:1280px) {
.emotion-0 {
-webkit-flex-basis: 25%;
-ms-flex-preferred-size: 25%;
flex-basis: 25%;
}
}
`;
exports[`Box should render without columns correctly 1`] = `
`;
================================================
FILE: packages/core/__tests__/__snapshots__/Ancestor_Grid_Test.bs.js.snap
================================================
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Grid should with spacing render correctly 1`] = `
@media (min-width:0px) {
.emotion-0 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-flex-wrap: wrap;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
width: calc(100% + 8px);
margin-left: -8px;
margin-top: -8px;
}
.emotion-0>* {
box-sizing: border-box;
padding-top: 8px;
padding-left: 8px;
}
}
@media (min-width:920px) {
.emotion-0 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-flex-wrap: wrap;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
width: calc(100% + 0px);
margin-left: -0px;
margin-top: -0px;
}
.emotion-0>* {
box-sizing: border-box;
padding-top: 0px;
padding-left: 0px;
}
}
@media (min-width:1280px) {
.emotion-0 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-flex-wrap: wrap;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
width: calc(100% + 24px);
margin-left: -24px;
margin-top: -24px;
}
.emotion-0>* {
box-sizing: border-box;
padding-top: 24px;
padding-left: 24px;
}
}
@media (min-width:0px) {
.emotion-2 {
-webkit-flex-basis: 50%;
-ms-flex-preferred-size: 50%;
flex-basis: 50%;
}
}
@media (min-width:920px) {
.emotion-2 {
-webkit-flex-basis: 33.333333333333336%;
-ms-flex-preferred-size: 33.333333333333336%;
flex-basis: 33.333333333333336%;
}
}
@media (min-width:1280px) {
.emotion-2 {
-webkit-flex-basis: 25%;
-ms-flex-preferred-size: 25%;
flex-basis: 25%;
}
}
Column 1
Column 2
Column 3
Column 4
`;
exports[`Grid should without spacing render correctly 1`] = `
.emotion-0 {
width: 100%;
-webkit-box-flex-wrap: wrap;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
@media (min-width:0px) {
.emotion-2 {
-webkit-flex-basis: 50%;
-ms-flex-preferred-size: 50%;
flex-basis: 50%;
}
}
@media (min-width:920px) {
.emotion-2 {
-webkit-flex-basis: 33.333333333333336%;
-ms-flex-preferred-size: 33.333333333333336%;
flex-basis: 33.333333333333336%;
}
}
@media (min-width:1280px) {
.emotion-2 {
-webkit-flex-basis: 25%;
-ms-flex-preferred-size: 25%;
flex-basis: 25%;
}
}
Column 1
Column 2
Column 3
Column 4
`;
================================================
FILE: packages/core/__tests__/__snapshots__/Ancestor_Hidden_Test.bs.js.snap
================================================
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Hidden should visually hide elements correctly 1`] = `
@media (min-width:0px) {
.emotion-0 {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-style: none;
}
}
@media (min-width:920px) {
.emotion-0 {
position: static;
width: auto;
height: auto;
padding: 0;
overflow: visible;
white-space: normal;
border-style: initial;
clip: initial;
}
}
@media (min-width:1280px) {
.emotion-0 {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-style: none;
}
}
`;
================================================
FILE: packages/core/__tests__/__snapshots__/Ancestor_Stack_Test.bs.js.snap
================================================
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Stack should render correctly 1`] = `
.emotion-0 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
@media (min-width:0px) {
.emotion-0 {
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
}
}
@media (min-width:920px) {
.emotion-0 {
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
}
}
`;
exports[`Stack should render with dividers correctly 1`] = `
.emotion-0 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
}
Placeholder
Divider
Placeholder
`;
================================================
FILE: packages/core/bsconfig.json
================================================
{
"name": "@ancestor-ui/core",
"version": "0.0.8-beta",
"sources": [
{
"dir": "scripts",
"type": "dev",
"subdirs": true
},
{
"dir": "__tests__",
"type": "dev",
"subdirs": true
},
{
"dir": "src",
"subdirs": true
}
],
"package-specs": [
{
"module": "commonjs",
"in-source": true
}
],
"jsx": { "version": 4, "mode": "classic" },
"suffix": ".bs.js",
"bs-dependencies": [
"@rescript/react",
"@ancestor-ui/bindings",
"@ancestor-ui/css",
"bs-css",
"bs-css-emotion"
],
"bs-dev-dependencies": ["rescript-nodejs", "@greenlabs/rescript-jest"],
"ppx-flags": []
}
================================================
FILE: packages/core/jest.config.js
================================================
module.exports = {
testMatch: ["**/*_Test.bs.js"],
snapshotSerializers: ["@emotion/jest/serializer"],
testEnvironment: "jsdom",
};
================================================
FILE: packages/core/package.json
================================================
{
"name": "@ancestor-ui/core",
"version": "0.7.1",
"main": "index.js",
"license": "MIT",
"keywords": [
"rescript",
"rescript-react",
"rescript ui library",
"rescript ui primitives",
"rescript unstyled components",
"ui library",
"layout primitives"
],
"devDependencies": {
"@babel/core": "7.17.5",
"@emotion/css": "11.10.0",
"@emotion/jest": "11.9.3",
"@greenlabs/rescript-jest": "1.0.1",
"@rescript/react": "0.11.0-rc.3",
"@storybook/addon-actions": "6.5.15",
"@storybook/addon-essentials": "6.5.15",
"@storybook/addon-interactions": "6.5.15",
"@storybook/addon-links": "6.5.15",
"@storybook/react": "6.5.15",
"@storybook/testing-library": "0.0.13",
"@testing-library/react-hooks": "8.0.1",
"babel-loader": "8.2.3",
"jest": "29.3.1",
"jsdom": "20.0.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-test-renderer": "18.2.0",
"rescript": "10.1.0",
"rescript-nodejs": "14.3.1"
},
"dependencies": {
"@ancestor-ui/bindings": "0.1.0",
"@ancestor-ui/css": "0.6.1"
},
"peerDependencies": {
"@rescript/react": ">=0.11",
"react": ">=18",
"react-dom": ">=18",
"rescript": ">=10"
},
"scripts": {
"build": "rescript build -with-deps",
"watch": "rescript build -w",
"clean": "rescript clean",
"format": "rescript format",
"test": "jest",
"generate-interface": "bsc -i",
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook",
"add-prop": "node scripts/AddProps.bs.js"
}
}
================================================
FILE: packages/core/scripts/AddProps.res
================================================
open Node
module Modules = {
type t = Base | Hidden | Stack | Grid | Box
let componentsPath = Path.join([NodeJs.Global.dirname, "..", "src", "components"])
let getPath = m => {
let modulePath = switch m {
| Base => ["base", "Ancestor_Base.res"]
| Hidden => ["hidden", "Ancestor_Hidden.res"]
| Box => ["box", "Ancestor_Box.res"]
| Grid => ["grid", "Ancestor_Grid.res"]
| Stack => ["stack", "Ancestor_Stack.res"]
}
Path.join([componentsPath]->Js.Array2.concat(modulePath))
}
let get = m => Fs.readFileSync(getPath(m), #utf8)->Js.String2.split("\n")
let write = (content, m) => {
let path = getPath(m)
Fs.writeFileSync(path, content, #utf8)
Child_process.execSync(`yarn rescript format ${path}`, Child_process.option())->ignore
}
}
module PropsCollector = {
type prefix = Start | End
module type Prefix = {
type t = prefix
let fromString: string => option
}
module type PrefixInterface = {
let startPrefix: Js.Re.t
let endPrefix: Js.Re.t
}
module MakePrefix = (M: PrefixInterface): Prefix => {
type t = prefix
let fromString = line => {
if M.startPrefix->Js.Re.test_(line) {
Some(Start)
} else if M.endPrefix->Js.Re.test_(line) {
Some(End)
} else {
None
}
}
}
module DeclarationPrefix = MakePrefix({
let startPrefix = "declaration:start"->Js.Re.fromStringWithFlags(~flags="ig")
let endPrefix = "declaration:end"->Js.Re.fromStringWithFlags(~flags="ig")
})
module ForwardFnPrefix = MakePrefix({
let startPrefix = "forward-fn:start"->Js.Re.fromStringWithFlags(~flags="ig")
let endPrefix = "forward-fn:end"->Js.Re.fromStringWithFlags(~flags="ig")
})
module ForwardPrefix = MakePrefix({
let startPrefix = "forward:start"->Js.Re.fromStringWithFlags(~flags="ig")
let endPrefix = "forward:end"->Js.Re.fromStringWithFlags(~flags="ig")
})
type lineCollector = {
collect: bool,
lines: array,
}
type collector<'prefix> = {
prefix: option<'prefix>,
head: array,
tail: array,
}
type api = {
props: array,
head: array,
tail: array,
}
let getPropsList = (lines, prefix: module(Prefix)) => {
let module(Prefix) = prefix
let collector = lines->Js.Array2.reduce((collector, line) => {
let prefix = Prefix.fromString(line)
switch (collector, prefix) {
| ({collect: true, lines}, None) => {
collect: true,
lines: lines->Js.Array2.concat([line]),
}
| ({collect: true, lines}, Some(End)) => {collect: false, lines}
| ({collect: false}, Some(Start)) => {collect: true, lines: []}
| (_, _) => collector
}
}, {collect: false, lines: []})
collector.lines
}
let extractLines = (lines, prefix: module(Prefix)) => {
let module(Prefix) = prefix
lines->Js.Array2.reduce((collector, line) => {
let prefix = Prefix.fromString(line)
switch (collector, prefix) {
| ({head, prefix: None}, None) => {
...collector,
head: head->Js.Array2.concat([line]),
}
| ({head, prefix: None}, Some(Start)) => {
...collector,
prefix: Some(Start),
head: head->Js.Array2.concat([line]),
}
| ({prefix: Some(Start), tail}, Some(End)) => {
...collector,
tail: tail->Js.Array2.concat([line]),
prefix: Some(End),
}
| ({prefix: Some(End), tail}, None) => {
...collector,
tail: tail->Js.Array2.concat([line]),
}
| _ => collector
}
}, {tail: [], head: [], prefix: None})
}
let extract = (fileContent, ~prefix: module(Prefix)) => {
let module(Prefix) = prefix
let propsList = fileContent->getPropsList(module(Prefix))
let fileLines = fileContent->extractLines(module(Prefix))
{
props: propsList,
head: fileLines.head,
tail: fileLines.tail,
}
}
}
module PropsUpdater = {
type t = Declaration | Forward | ForwardToFn
let updateList = (propsList, ~props, ~kind) => {
let updatedProps = props->Js.Array2.map(propName =>
switch kind {
| Declaration => `~${propName}=?,`
| Forward => `?${propName}`
| ForwardToFn => `?${propName},`
}
)
propsList->Js.Array2.concat(updatedProps)
}
let add = (fileContent, ~newProps, ~collectorPrefix: module(PropsCollector.Prefix), ~kind) => {
let moduleApi = PropsCollector.extract(fileContent, ~prefix=collectorPrefix)
let updatedDeclarationProps = moduleApi.props->updateList(~props=newProps, ~kind)
moduleApi.head->Js.Array2.concatMany([updatedDeclarationProps, moduleApi.tail])
}
}
/*
* Get the props list from the command args
*/
let newProps = Process.argv->Belt.Array.sliceToEnd(2)
/*
* All modules that are using responsive props
*/
let modules: array = [Base, Hidden, Stack, Grid, Box]
let updateModuleProps = (m: Modules.t) => {
let forwardKind = m === Base ? PropsUpdater.ForwardToFn : PropsUpdater.Forward
let prefixModule: module(PropsCollector.Prefix) =
m === Base ? module(PropsCollector.ForwardFnPrefix) : module(PropsCollector.ForwardPrefix)
Modules.get(m)
->PropsUpdater.add(
~collectorPrefix=module(PropsCollector.DeclarationPrefix),
~newProps,
~kind=Declaration,
)
->PropsUpdater.add(~collectorPrefix=prefixModule, ~newProps, ~kind=forwardKind)
->Js.Array2.joinWith("\n")
->Modules.write(m)
}
modules->Js.Array2.forEach(updateModuleProps)
================================================
FILE: packages/core/src/Ancestor.res
================================================
include Ancestor_Core
module Defaults = {
module Breakpoints = {
type breakpoints<'a> = {
xs?: 'a,
sm?: 'a,
md?: 'a,
lg?: 'a,
xl?: 'a,
}
type keyOfBreakpoints = AncestorCss.Defaults.Breakpoints.breakpoints
let encode = breakpoints => [
(#xs, breakpoints.xs),
(#sm, breakpoints.sm),
(#md, breakpoints.md),
(#lg, breakpoints.lg),
(#xl, breakpoints.xl),
]
let sizeByBreakpoints = AncestorCss.Defaults.Breakpoints.sizeByBreakpoints
}
module Spacing = AncestorCss.Defaults.Spacing
module Radius = AncestorCss.Defaults.Radius
module ZIndex = AncestorCss.Defaults.ZIndex
module Colors = AncestorCss.Defaults.Colors
module FontSize = AncestorCss.Defaults.FontSize
module FontWeight = AncestorCss.Defaults.FontWeight
module FontFamily = AncestorCss.Defaults.FontFamily
module LineHeight = AncestorCss.Defaults.LineHeight
module LetterSpacing = AncestorCss.Defaults.LetterSpacing
module Typography = AncestorCss.Defaults.Typography
module Shadows = AncestorCss.Defaults.Shadows
}
include Make(
Defaults.Breakpoints,
Defaults.Colors,
Defaults.Spacing,
Defaults.Radius,
Defaults.ZIndex,
Defaults.Typography,
Defaults.Shadows,
)
/*
* We need to expose the breakpoints record for the compiler.
*/
include Defaults.Breakpoints
================================================
FILE: packages/core/src/_helpers_/Ancestor_Helpers.res
================================================
open Ancestor
module Colors = {
let gray1 = #hex("616161")
let gray2 = #hex("d4d4d4")
}
module Placeholder = {
@react.component
let make = (~children=React.null, ~width={xs: 7.2->#rem}, ~height={xs: 7.2->#rem}) =>
#px}
fontWeight={xs: #num(700)}
display={xs: #flex}
justifyContent={xs: #center}
alignItems={xs: #center}
borderRadius={xs: 1}
border={xs: (2->#px, #solid, Colors.gray1)}
bgColor={xs: Colors.gray2}>
children
}
================================================
FILE: packages/core/src/bindings/Ancestor_React.res
================================================
type tags = [
| #a
| #abbr
| #acronym
| #address
| #applet
| #area
| #article
| #aside
| #audio
| #b
| #base
| #basefont
| #bdo
| #big
| #blockquote
| #body
| #br
| #button
| #canvas
| #caption
| #center
| #cite
| #code
| #col
| #colgroup
| #datalist
| #dd
| #del
| #dfn
| #div
| #dl
| #dt
| #em
| #embed
| #fieldset
| #figcaption
| #figure
| #font
| #footer
| #form
| #frame
| #frameset
| #head
| #header
| #h1
| #h2
| #h3
| #h3
| #h4
| #h5
| #h6
| #hr
| #html
| #i
| #iframe
| #img
| #input
| #ins
| #kbd
| #label
| #legend
| #li
| #link
| #main
| #map
| #mark
| #meta
| #meter
| #nav
| #noscript
| #object
| #ol
| #optgroup
| #option
| #p
| #param
| #pre
| #progress
| #q
| #s
| #samp
| #script
| #section
| #select
| #small
| #source
| #span
| #strike
| #strong
| #style
| #sub
| #sup
| #table
| #tbody
| #td
| #textarea
| #tfoot
| #th
| #thead
| #time
| #title
| #tr
| #u
| #ul
| #var
| #video
| #wbr
]
@module("react")
external createElement: (tags, ReactDOM.domProps, option) => React.element =
"createElement"
================================================
FILE: packages/core/src/bindings/Ancestor_TestingLibrary.res
================================================
type result<'a> = {current: 'a}
type renderHookResult<'a> = {result: result<'a>}
@module("@testing-library/react-hooks/native")
external renderHook: (unit => 'a) => renderHookResult<'a> = "renderHook"
@module("@testing-library/react-hooks/native")
external act: ((. unit) => unit) => unit = "act"
================================================
FILE: packages/core/src/components/base/Ancestor_Base.res
================================================
module Make = (Config: Ancestor_Config.T) => {
module Styles = Ancestor_Styles.Make(Config)
@react.component
let make = (
// declaration:start
~borderRadius=?,
~borderTLRadius=?,
~borderTRRadius=?,
~borderBLRadius=?,
~borderBRRadius=?,
~borderStyle=?,
~borderColor=?,
~borderWidth=?,
~borderRightStyle=?,
~borderLeftStyle=?,
~borderTopStyle=?,
~borderBottomStyle=?,
~borderRightColor=?,
~borderLeftColor=?,
~borderTopColor=?,
~borderBottomColor=?,
~borderRightWidth=?,
~borderLeftWidth=?,
~borderTopWidth=?,
~borderBottomWidth=?,
~border=?,
~borderRight=?,
~borderLeft=?,
~borderTop=?,
~borderBottom=?,
~bgColor=?,
~bgSize=?,
~bgPosition=?,
~bgImage=?,
~color=?,
~display=?,
~justifyContent=?,
~flexDirection=?,
~alignItems=?,
~flexBasis=?,
~flexWrap=?,
~flexGrow=?,
~alignContent=?,
~alignSelf=?,
~justifySelf=?,
~gap=?,
~p=?,
~px=?,
~py=?,
~pt=?,
~pb=?,
~pl=?,
~pr=?,
~m=?,
~mx=?,
~my=?,
~mt=?,
~mb=?,
~ml=?,
~mr=?,
~textAlign=?,
~fontFamily=?,
~fontWeight=?,
~fontSize=?,
~letterSpacing=?,
~lineHeight=?,
~width=?,
~height=?,
~minW=?,
~minH=?,
~maxW=?,
~maxH=?,
~position=?,
~top=?,
~bottom=?,
~left=?,
~right=?,
~zIndex=?,
~boxSizing=?,
~overflow=?,
~overflowX=?,
~overflowY=?,
~cursor=?,
~visibility=?,
~listStyleType=?,
~listStylePosition=?,
~listStyleImage=?,
~listStyle=?,
~outlineStyle=?,
~outline=?,
~textDecorationStyle=?,
~textDecorationLine=?,
~textDecoration=?,
~transform=?,
~_hover=?,
~_focus=?,
~_active=?,
~_focusWithin=?,
~_focusVisible=?,
~_disabled=?,
~_before=?,
~_after=?,
~_even=?,
~_odd=?,
~_first=?,
~_last=?,
~_notFirst=?,
~_notLast=?,
~transition=?,
~transitionProperty=?,
~transitionDelay=?,
~transitionDuration=?,
~transitionTimingFunction=?,
~transitions=?,
// declaration:end
// Base props
~tag: Ancestor_React.tags=#div,
// React props
~innerRef=?,
~dangerouslySetInnerHTML=?,
// DOM Props
~className="",
~children=?,
~id=?,
~onClick=?,
~onSubmit=?,
~onChange=?,
~alt=?,
~src=?,
~ariaDetails=?,
~ariaDisabled=?,
~ariaHidden=?,
~ariaKeyshortcuts=?,
~ariaLabel=?,
~ariaRoledescription=?,
~ariaExpanded=?,
~ariaLevel=?,
~ariaModal=?,
~ariaMultiline=?,
~ariaMultiselectable=?,
~ariaPlaceholder=?,
~ariaReadonly=?,
~ariaRequired=?,
~ariaSelected=?,
~ariaSort=?,
~ariaValuemax=?,
~ariaValuemin=?,
~ariaValuenow=?,
~ariaValuetext=?,
~ariaAtomic=?,
~ariaBusy=?,
~ariaRelevant=?,
~ariaGrabbed=?,
~ariaActivedescendant=?,
~ariaColcount=?,
~ariaColindex=?,
~ariaColspan=?,
~ariaControls=?,
~ariaDescribedby=?,
~ariaErrormessage=?,
~ariaFlowto=?,
~ariaLabelledby=?,
~ariaOwns=?,
~ariaPosinset=?,
~ariaRowcount=?,
~ariaRowindex=?,
~ariaRowspan=?,
~ariaSetsize=?,
~defaultChecked=?,
~defaultValue=?,
~accessKey=?,
~contentEditable=?,
~contextMenu=?,
~lang=?,
~role=?,
~style=?,
~spellCheck=?,
~tabIndex=?,
~title=?,
~itemID=?,
~itemProp=?,
~itemRef=?,
~itemScope=?,
~itemType=?,
~accept=?,
~acceptCharset=?,
~action=?,
~allowFullScreen=?,
~async=?,
~autoComplete=?,
~autoCapitalize=?,
~autoFocus=?,
~autoPlay=?,
~challenge=?,
~charSet=?,
~checked=?,
~cite=?,
~crossOrigin=?,
~cols=?,
~colSpan=?,
~content=?,
~controls=?,
~coords=?,
~data=?,
~dateTime=?,
~default=?,
~defer=?,
~disabled=?,
~download=?,
~encType=?,
~form=?,
~formAction=?,
~formTarget=?,
~formMethod=?,
~headers=?,
~high=?,
~href=?,
~hrefLang=?,
~htmlFor=?,
~httpEquiv=?,
~icon=?,
~inputMode=?,
~integrity=?,
~keyType=?,
~kind=?,
~label=?,
~list=?,
~loop=?,
~low=?,
~manifest=?,
~max=?,
~maxLength=?,
~media=?,
~mediaGroup=?,
~method=?,
~min=?,
~minLength=?,
~multiple=?,
~muted=?,
~name=?,
~nonce=?,
~noValidate=?,
~open_=?,
~optimum=?,
~pattern=?,
~placeholder=?,
~playsInline=?,
~poster=?,
~preload=?,
~radioGroup=?,
~readOnly=?,
~rel=?,
~required=?,
~reversed=?,
~rows=?,
~rowSpan=?,
~sandbox=?,
~scope=?,
~scoped=?,
~scrolling=?,
~selected=?,
~shape=?,
~size=?,
~sizes=?,
~span=?,
~srcDoc=?,
~srcLang=?,
~srcSet=?,
~start=?,
~step=?,
~summary=?,
~target=?,
~type_=?,
~useMap=?,
~value=?,
~wrap=?,
~onCopy=?,
~onCut=?,
~onPaste=?,
~onCompositionEnd=?,
~onCompositionStart=?,
~onCompositionUpdate=?,
~onKeyDown=?,
~onKeyPress=?,
~onKeyUp=?,
~onFocus=?,
~onBlur=?,
~onInput=?,
~onInvalid=?,
~onContextMenu=?,
~onDoubleClick=?,
~onDrag=?,
~onDragEnd=?,
~onDragEnter=?,
~onDragExit=?,
~onDragLeave=?,
~onDragOver=?,
~onDragStart=?,
~onDrop=?,
~onMouseDown=?,
~onMouseEnter=?,
~onMouseLeave=?,
~onMouseMove=?,
~onMouseOut=?,
~onMouseOver=?,
~onMouseUp=?,
~onSelect=?,
~onTouchCancel=?,
~onTouchEnd=?,
~onTouchMove=?,
~onTouchStart=?,
~onPointerOver=?,
~onPointerEnter=?,
~onPointerDown=?,
~onPointerMove=?,
~onPointerUp=?,
~onPointerCancel=?,
~onPointerOut=?,
~onPointerLeave=?,
~onGotPointerCapture=?,
~onLostPointerCapture=?,
~onScroll=?,
~onWheel=?,
~onAbort=?,
~onCanPlay=?,
~onCanPlayThrough=?,
~onDurationChange=?,
~onEmptied=?,
~onEnded=?,
~onError=?,
~onLoadedData=?,
~onLoadedMetadata=?,
~onLoadStart=?,
~onPause=?,
~onPlay=?,
~onPlaying=?,
~onProgress=?,
~onRateChange=?,
~onSeeked=?,
~onSeeking=?,
~onStalled=?,
~onSuspend=?,
~onTimeUpdate=?,
~onVolumeChange=?,
~onWaiting=?,
~onLoad=?,
~onAnimationStart=?,
~onAnimationEnd=?,
~onAnimationIteration=?,
~onTransitionEnd=?,
) => {
let componentClassName = {
let responsiveStyles = Styles.createResponsiveStyles(
// forward-fn:start
~borderRadius?,
~borderTLRadius?,
~borderTRRadius?,
~borderBLRadius?,
~borderBRRadius?,
~borderStyle?,
~borderColor?,
~borderWidth?,
~borderRightStyle?,
~borderLeftStyle?,
~borderTopStyle?,
~borderBottomStyle?,
~borderRightColor?,
~borderLeftColor?,
~borderTopColor?,
~borderBottomColor?,
~borderRightWidth?,
~borderLeftWidth?,
~borderTopWidth?,
~borderBottomWidth?,
~border?,
~borderRight?,
~borderLeft?,
~borderTop?,
~borderBottom?,
~bgColor?,
~bgSize?,
~bgPosition?,
~bgImage?,
~color?,
~display?,
~justifyContent?,
~flexDirection?,
~alignItems?,
~flexBasis?,
~flexWrap?,
~flexGrow?,
~alignContent?,
~alignSelf?,
~justifySelf?,
~gap?,
~p?,
~py?,
~px?,
~pt?,
~pb?,
~pl?,
~pr?,
~m?,
~mx?,
~my?,
~mt?,
~mb?,
~ml?,
~mr?,
~textAlign?,
~fontFamily?,
~fontWeight?,
~fontSize?,
~letterSpacing?,
~lineHeight?,
~width?,
~height?,
~minW?,
~minH?,
~maxW?,
~maxH?,
~position?,
~top?,
~bottom?,
~left?,
~right?,
~zIndex?,
~boxSizing?,
~overflow?,
~overflowX?,
~overflowY?,
~cursor?,
~visibility?,
~listStyleType?,
~listStylePosition?,
~listStyleImage?,
~listStyle?,
~outlineStyle?,
~outline?,
~textDecorationStyle?,
~textDecorationLine?,
~textDecoration?,
~transform?,
~_hover?,
~_focus?,
~_active?,
~_focusWithin?,
~_focusVisible?,
~_disabled?,
~_before?,
~_after?,
~_even?,
~_odd?,
~_first?,
~_last?,
~_notFirst?,
~_notLast?,
~transition?,
~transitionProperty?,
~transitionDelay?,
~transitionDuration?,
~transitionTimingFunction?,
~transitions?,
// forward-fn:end
(),
)
`${className} ${responsiveStyles}`
}
Ancestor_React.createElement(
tag,
{
className: componentClassName,
?id,
?onClick,
?onSubmit,
?onChange,
?src,
?alt,
?dangerouslySetInnerHTML,
ref: ?innerRef,
?ariaDetails,
?ariaDisabled,
?ariaHidden,
?ariaKeyshortcuts,
?ariaLabel,
?ariaRoledescription,
?ariaExpanded,
?ariaLevel,
?ariaModal,
?ariaMultiline,
?ariaMultiselectable,
?ariaPlaceholder,
?ariaReadonly,
?ariaRequired,
?ariaSelected,
?ariaSort,
?ariaValuemax,
?ariaValuemin,
?ariaValuenow,
?ariaValuetext,
?ariaAtomic,
?ariaBusy,
?ariaRelevant,
?ariaGrabbed,
?ariaActivedescendant,
?ariaColcount,
?ariaColindex,
?ariaColspan,
?ariaControls,
?ariaDescribedby,
?ariaErrormessage,
?ariaFlowto,
?ariaLabelledby,
?ariaOwns,
?ariaPosinset,
?ariaRowcount,
?ariaRowindex,
?ariaRowspan,
?ariaSetsize,
?defaultChecked,
?defaultValue,
?accessKey,
?contentEditable,
?contextMenu,
?lang,
?role,
?style,
?spellCheck,
?tabIndex,
?title,
?itemID,
?itemProp,
?itemRef,
?itemScope,
?itemType,
?accept,
?acceptCharset,
?action,
?allowFullScreen,
?async,
?autoComplete,
?autoCapitalize,
?autoFocus,
?autoPlay,
?challenge,
?charSet,
?checked,
?cite,
?crossOrigin,
?cols,
?colSpan,
?content,
?controls,
?coords,
?data,
?dateTime,
?default,
?defer,
?disabled,
?download,
?encType,
?form,
?formAction,
?formTarget,
?formMethod,
?headers,
?high,
?href,
?hrefLang,
?htmlFor,
?httpEquiv,
?icon,
?inputMode,
?integrity,
?keyType,
?kind,
?label,
?list,
?loop,
?low,
?manifest,
?max,
?maxLength,
?media,
?mediaGroup,
?method,
?min,
?minLength,
?multiple,
?muted,
?name,
?nonce,
?noValidate,
?open_,
?optimum,
?pattern,
?placeholder,
?playsInline,
?poster,
?preload,
?radioGroup,
?readOnly,
?rel,
?required,
?reversed,
?rows,
?rowSpan,
?sandbox,
?scope,
?scoped,
?scrolling,
?selected,
?shape,
?size,
?sizes,
?span,
?srcDoc,
?srcLang,
?srcSet,
?start,
?step,
?summary,
?target,
?type_,
?useMap,
?value,
?wrap,
?onCopy,
?onCut,
?onPaste,
?onCompositionEnd,
?onCompositionStart,
?onCompositionUpdate,
?onKeyDown,
?onKeyPress,
?onKeyUp,
?onFocus,
?onBlur,
?onInput,
?onInvalid,
?onContextMenu,
?onDoubleClick,
?onDrag,
?onDragEnd,
?onDragEnter,
?onDragExit,
?onDragLeave,
?onDragOver,
?onDragStart,
?onDrop,
?onMouseDown,
?onMouseEnter,
?onMouseLeave,
?onMouseMove,
?onMouseOut,
?onMouseOver,
?onMouseUp,
?onSelect,
?onTouchCancel,
?onTouchEnd,
?onTouchMove,
?onTouchStart,
?onPointerOver,
?onPointerEnter,
?onPointerDown,
?onPointerMove,
?onPointerUp,
?onPointerCancel,
?onPointerOut,
?onPointerLeave,
?onGotPointerCapture,
?onLostPointerCapture,
?onScroll,
?onWheel,
?onAbort,
?onCanPlay,
?onCanPlayThrough,
?onDurationChange,
?onEmptied,
?onEnded,
?onError,
?onLoadedData,
?onLoadedMetadata,
?onLoadStart,
?onPause,
?onPlay,
?onPlaying,
?onProgress,
?onRateChange,
?onSeeked,
?onSeeking,
?onStalled,
?onSuspend,
?onTimeUpdate,
?onVolumeChange,
?onWaiting,
?onLoad,
?onAnimationStart,
?onAnimationEnd,
?onAnimationIteration,
?onTransitionEnd,
},
children,
)
}
}
================================================
FILE: packages/core/src/components/base/Ancestor_Base_Stories.res
================================================
open Ancestor
let default = Storybook.story(~title="Components/Base", ())
let basicUsage = () => {
let s = React.string
open Css
#percent}>
#px}
borderRadius={xs: 1}
p={xs: 3}
bgColor={xs: #hex("000"), md: #hex("fc0"), lg: #hex("f36")}
tag=#section>
#px, #solid, #hex("f36"))}
borderRadius={xs: 6}
height={xs: 96->#px}
width={xs: 96->#px}
src="https://ancestor.rescriptbrasil.org/img/ww-picture.png"
tag=#img
mb={xs: 2}
/>
#px} tag=#h1>
{"Walter White"->s}
#px} tag=#p>
{"Teacher"->s}
#px}
lineHeight={xs: 2.4->#rem}
tag=#p>
{"Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old"->s}
}
================================================
FILE: packages/core/src/components/box/Ancestor_Box.res
================================================
module Make = (Config: Ancestor_Config.T) => {
module Styles = Ancestor_Styles.Make(Config)
module Base = Ancestor_Base.Make(Config)
type columns = [
| #1
| #2
| #3
| #4
| #5
| #6
| #7
| #8
| #9
| #10
| #11
| #12
]
/**
* Calculate the columns size based on the value provided.
*/
let basisFromFloat = (value: columns) => (value :> int)->Js.Int.toFloat->(v => v *. 100.0 /. 12.0)
/**
* Specific styles for the API.
*/
let createBox = (~columns=?, ()) => {
open Styles.Css
let responsiveStyles = Styles.createResponsiveProp(~prop=columns, column => [
flexBasis(column->basisFromFloat->#percent),
])
style(. responsiveStyles)
}
@react.component
let make = (
// declaration:start
~borderRadius=?,
~borderTLRadius=?,
~borderTRRadius=?,
~borderBLRadius=?,
~borderBRRadius=?,
~borderStyle=?,
~borderColor=?,
~borderWidth=?,
~borderRightStyle=?,
~borderLeftStyle=?,
~borderTopStyle=?,
~borderBottomStyle=?,
~borderRightColor=?,
~borderLeftColor=?,
~borderTopColor=?,
~borderBottomColor=?,
~borderRightWidth=?,
~borderLeftWidth=?,
~borderTopWidth=?,
~borderBottomWidth=?,
~border=?,
~borderRight=?,
~borderLeft=?,
~borderTop=?,
~borderBottom=?,
~bgColor=?,
~bgSize=?,
~bgPosition=?,
~bgImage=?,
~color=?,
~display=?,
~justifyContent=?,
~flexDirection=?,
~alignItems=?,
~flexBasis=?,
~flexWrap=?,
~flexGrow=?,
~alignContent=?,
~alignSelf=?,
~justifySelf=?,
~gap=?,
~p=?,
~px=?,
~py=?,
~pt=?,
~pb=?,
~pl=?,
~pr=?,
~m=?,
~mx=?,
~my=?,
~mt=?,
~mb=?,
~ml=?,
~mr=?,
~textAlign=?,
~fontFamily=?,
~fontWeight=?,
~fontSize=?,
~letterSpacing=?,
~lineHeight=?,
~width=?,
~height=?,
~minW=?,
~minH=?,
~maxW=?,
~maxH=?,
~position=?,
~top=?,
~bottom=?,
~left=?,
~right=?,
~zIndex=?,
~boxSizing=?,
~overflow=?,
~overflowX=?,
~overflowY=?,
~cursor=?,
~visibility=?,
~listStyleType=?,
~listStylePosition=?,
~listStyleImage=?,
~listStyle=?,
~outlineStyle=?,
~outline=?,
~textDecorationStyle=?,
~textDecorationLine=?,
~textDecoration=?,
~transform=?,
~_hover=?,
~_focus=?,
~_active=?,
~_focusWithin=?,
~_focusVisible=?,
~_disabled=?,
~_before=?,
~_after=?,
~_even=?,
~_odd=?,
~_first=?,
~_last=?,
~_notFirst=?,
~_notLast=?,
~transition=?,
~transitionProperty=?,
~transitionDelay=?,
~transitionDuration=?,
~transitionTimingFunction=?,
~transitions=?,
// declaration:end
// Box props
~columns: option>=?,
// React props
~children=?,
~dangerouslySetInnerHTML=?,
~innerRef=?,
// DOM Props
~className="",
~tag: Ancestor_React.tags=#div,
~id=?,
~onClick=?,
~onSubmit=?,
~onChange=?,
~src=?,
~alt=?,
~ariaDetails=?,
~ariaDisabled=?,
~ariaHidden=?,
~ariaKeyshortcuts=?,
~ariaLabel=?,
~ariaRoledescription=?,
~ariaExpanded=?,
~ariaLevel=?,
~ariaModal=?,
~ariaMultiline=?,
~ariaMultiselectable=?,
~ariaPlaceholder=?,
~ariaReadonly=?,
~ariaRequired=?,
~ariaSelected=?,
~ariaSort=?,
~ariaValuemax=?,
~ariaValuemin=?,
~ariaValuenow=?,
~ariaValuetext=?,
~ariaAtomic=?,
~ariaBusy=?,
~ariaRelevant=?,
~ariaGrabbed=?,
~ariaActivedescendant=?,
~ariaColcount=?,
~ariaColindex=?,
~ariaColspan=?,
~ariaControls=?,
~ariaDescribedby=?,
~ariaErrormessage=?,
~ariaFlowto=?,
~ariaLabelledby=?,
~ariaOwns=?,
~ariaPosinset=?,
~ariaRowcount=?,
~ariaRowindex=?,
~ariaRowspan=?,
~ariaSetsize=?,
~defaultChecked=?,
~defaultValue=?,
~accessKey=?,
~contentEditable=?,
~contextMenu=?,
~lang=?,
~role=?,
~style=?,
~spellCheck=?,
~tabIndex=?,
~title=?,
~itemID=?,
~itemProp=?,
~itemRef=?,
~itemScope=?,
~itemType=?,
~accept=?,
~acceptCharset=?,
~action=?,
~allowFullScreen=?,
~async=?,
~autoComplete=?,
~autoCapitalize=?,
~autoFocus=?,
~autoPlay=?,
~challenge=?,
~charSet=?,
~checked=?,
~cite=?,
~crossOrigin=?,
~cols=?,
~colSpan=?,
~content=?,
~controls=?,
~coords=?,
~data=?,
~dateTime=?,
~default=?,
~defer=?,
~disabled=?,
~download=?,
~encType=?,
~form=?,
~formAction=?,
~formTarget=?,
~formMethod=?,
~headers=?,
~high=?,
~href=?,
~hrefLang=?,
~htmlFor=?,
~httpEquiv=?,
~icon=?,
~inputMode=?,
~integrity=?,
~keyType=?,
~kind=?,
~label=?,
~list=?,
~loop=?,
~low=?,
~manifest=?,
~max=?,
~maxLength=?,
~media=?,
~mediaGroup=?,
~method=?,
~min=?,
~minLength=?,
~multiple=?,
~muted=?,
~name=?,
~nonce=?,
~noValidate=?,
~open_=?,
~optimum=?,
~pattern=?,
~placeholder=?,
~playsInline=?,
~poster=?,
~preload=?,
~radioGroup=?,
~readOnly=?,
~rel=?,
~required=?,
~reversed=?,
~rows=?,
~rowSpan=?,
~sandbox=?,
~scope=?,
~scoped=?,
~scrolling=?,
~selected=?,
~shape=?,
~size=?,
~sizes=?,
~span=?,
~srcDoc=?,
~srcLang=?,
~srcSet=?,
~start=?,
~step=?,
~summary=?,
~target=?,
~type_=?,
~useMap=?,
~value=?,
~wrap=?,
~onCopy=?,
~onCut=?,
~onPaste=?,
~onCompositionEnd=?,
~onCompositionStart=?,
~onCompositionUpdate=?,
~onKeyDown=?,
~onKeyPress=?,
~onKeyUp=?,
~onFocus=?,
~onBlur=?,
~onInput=?,
~onInvalid=?,
~onContextMenu=?,
~onDoubleClick=?,
~onDrag=?,
~onDragEnd=?,
~onDragEnter=?,
~onDragExit=?,
~onDragLeave=?,
~onDragOver=?,
~onDragStart=?,
~onDrop=?,
~onMouseDown=?,
~onMouseEnter=?,
~onMouseLeave=?,
~onMouseMove=?,
~onMouseOut=?,
~onMouseOver=?,
~onMouseUp=?,
~onSelect=?,
~onTouchCancel=?,
~onTouchEnd=?,
~onTouchMove=?,
~onTouchStart=?,
~onPointerOver=?,
~onPointerEnter=?,
~onPointerDown=?,
~onPointerMove=?,
~onPointerUp=?,
~onPointerCancel=?,
~onPointerOut=?,
~onPointerLeave=?,
~onGotPointerCapture=?,
~onLostPointerCapture=?,
~onScroll=?,
~onWheel=?,
~onAbort=?,
~onCanPlay=?,
~onCanPlayThrough=?,
~onDurationChange=?,
~onEmptied=?,
~onEnded=?,
~onError=?,
~onLoadedData=?,
~onLoadedMetadata=?,
~onLoadStart=?,
~onPause=?,
~onPlay=?,
~onPlaying=?,
~onProgress=?,
~onRateChange=?,
~onSeeked=?,
~onSeeking=?,
~onStalled=?,
~onSuspend=?,
~onTimeUpdate=?,
~onVolumeChange=?,
~onWaiting=?,
~onLoad=?,
~onAnimationStart=?,
~onAnimationEnd=?,
~onAnimationIteration=?,
~onTransitionEnd=?,
) => {
}
}
================================================
FILE: packages/core/src/components/box/Ancestor_Box_Stories.res
================================================
open Ancestor
let default = Storybook.story(~title="Components/Box", ())
let basicUsage = () => {
let s = React.string
#rem}
color={xs: #hex("fff")}
tag=#h1>
{`Start using right now`->s}
#rem}
fontWeight={xs: #num(300)}
color={xs: #hex("b1b1b1")}
lineHeight={xs: 2.8->#rem}
tag=#p>
{`Ancestor is production-ready and actively maintained. It’s used in production projects daily and keep breaking changes to a minimum whereever possible.`->s}
}
================================================
FILE: packages/core/src/components/grid/Ancestor_Grid.res
================================================
module Make = (Config: Ancestor_Config.T) => {
module Styles = Ancestor_Styles.Make(Config)
module Base = Ancestor_Base.Make(Config)
module LocalStyles = {
open Styles.Css
let defaultStyles = [width(100.->#percent), flexWrap(wrap), display(#flex)]
let grid = (~spacing=?, ()) => {
let spacingStyles = Styles.createResponsiveProp(~prop=spacing, ~defaultStyles, spacing => {
let spacingInPx = spacing->Config.spacing->Css_AtomicTypes.Length.toString
[
display(#flex),
flexWrap(wrap),
width(#calc(#add, 100.0->#percent, spacing->Config.spacing)),
marginLeft(spacing),
marginTop(spacing),
selector(. "> *", [boxSizing(borderBox), paddingTop(spacing), paddingLeft(spacing)]),
unsafe("marginLeft", `-${spacingInPx}`),
unsafe("marginTop", `-${spacingInPx}`),
]
})
style(. spacingStyles)
}
}
@react.component
let make = (
// declaration:start
~borderRadius=?,
~borderTLRadius=?,
~borderTRRadius=?,
~borderBLRadius=?,
~borderBRRadius=?,
~borderStyle=?,
~borderColor=?,
~borderWidth=?,
~borderRightStyle=?,
~borderLeftStyle=?,
~borderTopStyle=?,
~borderBottomStyle=?,
~borderRightColor=?,
~borderLeftColor=?,
~borderTopColor=?,
~borderBottomColor=?,
~borderRightWidth=?,
~borderLeftWidth=?,
~borderTopWidth=?,
~borderBottomWidth=?,
~border=?,
~borderRight=?,
~borderLeft=?,
~borderTop=?,
~borderBottom=?,
~bgColor=?,
~bgSize=?,
~bgPosition=?,
~bgImage=?,
~color=?,
~display=?,
~justifyContent=?,
~flexDirection=?,
~alignItems=?,
~flexBasis=?,
~flexWrap=?,
~flexGrow=?,
~alignContent=?,
~alignSelf=?,
~justifySelf=?,
~gap=?,
~p=?,
~px=?,
~py=?,
~pt=?,
~pb=?,
~pl=?,
~pr=?,
~m=?,
~mx=?,
~my=?,
~mt=?,
~mb=?,
~ml=?,
~mr=?,
~textAlign=?,
~fontFamily=?,
~fontWeight=?,
~fontSize=?,
~letterSpacing=?,
~lineHeight=?,
~width=?,
~height=?,
~minW=?,
~minH=?,
~maxW=?,
~maxH=?,
~position=?,
~top=?,
~bottom=?,
~left=?,
~right=?,
~zIndex=?,
~boxSizing=?,
~overflow=?,
~overflowX=?,
~overflowY=?,
~cursor=?,
~visibility=?,
~listStyleType=?,
~listStylePosition=?,
~listStyleImage=?,
~listStyle=?,
~outlineStyle=?,
~outline=?,
~textDecorationStyle=?,
~textDecorationLine=?,
~textDecoration=?,
~transform=?,
~_hover=?,
~_focus=?,
~_active=?,
~_focusWithin=?,
~_focusVisible=?,
~_disabled=?,
~_before=?,
~_after=?,
~_even=?,
~_odd=?,
~_first=?,
~_last=?,
~_notFirst=?,
~_notLast=?,
~transition=?,
~transitionProperty=?,
~transitionDelay=?,
~transitionDuration=?,
~transitionTimingFunction=?,
~transitions=?,
// declaration:end
// Grid props
~spacing: option>=?,
~tag: Ancestor_React.tags=#div,
// React props
~children=?,
~dangerouslySetInnerHTML=?,
~innerRef=?,
// DOM Props
~className="",
~id=?,
~onClick=?,
~onSubmit=?,
~onChange=?,
~src=?,
~alt=?,
~ariaDetails=?,
~ariaDisabled=?,
~ariaHidden=?,
~ariaKeyshortcuts=?,
~ariaLabel=?,
~ariaRoledescription=?,
~ariaExpanded=?,
~ariaLevel=?,
~ariaModal=?,
~ariaMultiline=?,
~ariaMultiselectable=?,
~ariaPlaceholder=?,
~ariaReadonly=?,
~ariaRequired=?,
~ariaSelected=?,
~ariaSort=?,
~ariaValuemax=?,
~ariaValuemin=?,
~ariaValuenow=?,
~ariaValuetext=?,
~ariaAtomic=?,
~ariaBusy=?,
~ariaRelevant=?,
~ariaGrabbed=?,
~ariaActivedescendant=?,
~ariaColcount=?,
~ariaColindex=?,
~ariaColspan=?,
~ariaControls=?,
~ariaDescribedby=?,
~ariaErrormessage=?,
~ariaFlowto=?,
~ariaLabelledby=?,
~ariaOwns=?,
~ariaPosinset=?,
~ariaRowcount=?,
~ariaRowindex=?,
~ariaRowspan=?,
~ariaSetsize=?,
~defaultChecked=?,
~defaultValue=?,
~accessKey=?,
~contentEditable=?,
~contextMenu=?,
~lang=?,
~role=?,
~style=?,
~spellCheck=?,
~tabIndex=?,
~title=?,
~itemID=?,
~itemProp=?,
~itemRef=?,
~itemScope=?,
~itemType=?,
~accept=?,
~acceptCharset=?,
~action=?,
~allowFullScreen=?,
~async=?,
~autoComplete=?,
~autoCapitalize=?,
~autoFocus=?,
~autoPlay=?,
~challenge=?,
~charSet=?,
~checked=?,
~cite=?,
~crossOrigin=?,
~cols=?,
~colSpan=?,
~content=?,
~controls=?,
~coords=?,
~data=?,
~dateTime=?,
~default=?,
~defer=?,
~disabled=?,
~download=?,
~encType=?,
~form=?,
~formAction=?,
~formTarget=?,
~formMethod=?,
~headers=?,
~high=?,
~href=?,
~hrefLang=?,
~htmlFor=?,
~httpEquiv=?,
~icon=?,
~inputMode=?,
~integrity=?,
~keyType=?,
~kind=?,
~label=?,
~list=?,
~loop=?,
~low=?,
~manifest=?,
~max=?,
~maxLength=?,
~media=?,
~mediaGroup=?,
~method=?,
~min=?,
~minLength=?,
~multiple=?,
~muted=?,
~name=?,
~nonce=?,
~noValidate=?,
~open_=?,
~optimum=?,
~pattern=?,
~placeholder=?,
~playsInline=?,
~poster=?,
~preload=?,
~radioGroup=?,
~readOnly=?,
~rel=?,
~required=?,
~reversed=?,
~rows=?,
~rowSpan=?,
~sandbox=?,
~scope=?,
~scoped=?,
~scrolling=?,
~selected=?,
~shape=?,
~size=?,
~sizes=?,
~span=?,
~srcDoc=?,
~srcLang=?,
~srcSet=?,
~start=?,
~step=?,
~summary=?,
~target=?,
~type_=?,
~useMap=?,
~value=?,
~wrap=?,
~onCopy=?,
~onCut=?,
~onPaste=?,
~onCompositionEnd=?,
~onCompositionStart=?,
~onCompositionUpdate=?,
~onKeyDown=?,
~onKeyPress=?,
~onKeyUp=?,
~onFocus=?,
~onBlur=?,
~onInput=?,
~onInvalid=?,
~onContextMenu=?,
~onDoubleClick=?,
~onDrag=?,
~onDragEnd=?,
~onDragEnter=?,
~onDragExit=?,
~onDragLeave=?,
~onDragOver=?,
~onDragStart=?,
~onDrop=?,
~onMouseDown=?,
~onMouseEnter=?,
~onMouseLeave=?,
~onMouseMove=?,
~onMouseOut=?,
~onMouseOver=?,
~onMouseUp=?,
~onSelect=?,
~onTouchCancel=?,
~onTouchEnd=?,
~onTouchMove=?,
~onTouchStart=?,
~onPointerOver=?,
~onPointerEnter=?,
~onPointerDown=?,
~onPointerMove=?,
~onPointerUp=?,
~onPointerCancel=?,
~onPointerOut=?,
~onPointerLeave=?,
~onGotPointerCapture=?,
~onLostPointerCapture=?,
~onScroll=?,
~onWheel=?,
~onAbort=?,
~onCanPlay=?,
~onCanPlayThrough=?,
~onDurationChange=?,
~onEmptied=?,
~onEnded=?,
~onError=?,
~onLoadedData=?,
~onLoadedMetadata=?,
~onLoadStart=?,
~onPause=?,
~onPlay=?,
~onPlaying=?,
~onProgress=?,
~onRateChange=?,
~onSeeked=?,
~onSeeking=?,
~onStalled=?,
~onSuspend=?,
~onTimeUpdate=?,
~onVolumeChange=?,
~onWaiting=?,
~onLoad=?,
~onAnimationStart=?,
~onAnimationEnd=?,
~onAnimationIteration=?,
~onTransitionEnd=?,
) => {
}
}
================================================
FILE: packages/core/src/components/grid/Ancestor_Grid_Stories.res
================================================
open Ancestor
let default = Storybook.story(~title="Components/Grid", ())
let basicUsage = () => {
let placeholder = Emotion.rawCss(`
padding: 32px;
border: solid 2px #f36;
background: #ff336629;
text-align: center;
font-weight: 700;
color: #f36;
border-radius: 4px;
font-size: 1.8rem;
width: 100%;
`)
{"6"->React.string}
{"6"->React.string}
{"12"->React.string}
{"4"->React.string}
{"4"->React.string}
{"4"->React.string}
}
================================================
FILE: packages/core/src/components/hidden/Ancestor_Hidden.res
================================================
module Make = (Config: Ancestor_Config.T) => {
module Styles = Ancestor_Styles.Make(Config)
module Base = Ancestor_Base.Make(Config)
let createHidden = (~on, ()) => {
open Styles.Css
/**
* Reference: https://github.com/twbs/bootstrap/blob/main/scss/mixins/_visually-hidden.scss#L8
*/
let hiddenStyles = [
position(absolute),
width(1->#px),
height(1->#px),
CssJs.padding(#zero),
overflow(#hidden),
unsafe("clip", "rect(0, 0, 0, 0)"),
whiteSpace(#nowrap),
borderStyle(#none),
]
let visibleStyles = [
position(#static),
width(#auto),
height(#auto),
CssJs.padding(#zero),
overflow(#visible),
whiteSpace(#normal),
borderStyle(#initial),
unsafe("clip", "initial"),
]
let onStyles = Styles.createResponsiveProp(~prop=on, on =>
switch on {
| false => visibleStyles
| true => hiddenStyles
}
)
style(. onStyles)
}
@react.component
let make = (
~on: option>=?,
// declaration:start
~borderRadius=?,
~borderTLRadius=?,
~borderTRRadius=?,
~borderBLRadius=?,
~borderBRRadius=?,
~borderStyle=?,
~borderColor=?,
~borderWidth=?,
~borderRightStyle=?,
~borderLeftStyle=?,
~borderTopStyle=?,
~borderBottomStyle=?,
~borderRightColor=?,
~borderLeftColor=?,
~borderTopColor=?,
~borderBottomColor=?,
~borderRightWidth=?,
~borderLeftWidth=?,
~borderTopWidth=?,
~borderBottomWidth=?,
~border=?,
~borderRight=?,
~borderLeft=?,
~borderTop=?,
~borderBottom=?,
~bgColor=?,
~bgSize=?,
~bgPosition=?,
~bgImage=?,
~color=?,
~display=?,
~justifyContent=?,
~flexDirection=?,
~alignItems=?,
~flexBasis=?,
~flexWrap=?,
~flexGrow=?,
~alignContent=?,
~alignSelf=?,
~justifySelf=?,
~gap=?,
~p=?,
~px=?,
~py=?,
~pt=?,
~pb=?,
~pl=?,
~pr=?,
~m=?,
~mx=?,
~my=?,
~mt=?,
~mb=?,
~ml=?,
~mr=?,
~textAlign=?,
~fontFamily=?,
~fontWeight=?,
~fontSize=?,
~letterSpacing=?,
~lineHeight=?,
~width=?,
~height=?,
~minW=?,
~minH=?,
~maxW=?,
~maxH=?,
~position=?,
~top=?,
~bottom=?,
~left=?,
~right=?,
~zIndex=?,
~boxSizing=?,
~overflow=?,
~overflowX=?,
~overflowY=?,
~cursor=?,
~visibility=?,
~listStyleType=?,
~listStylePosition=?,
~listStyleImage=?,
~listStyle=?,
~outlineStyle=?,
~outline=?,
~textDecorationStyle=?,
~textDecorationLine=?,
~textDecoration=?,
~transform=?,
~_hover=?,
~_focus=?,
~_active=?,
~_focusWithin=?,
~_focusVisible=?,
~_disabled=?,
~_before=?,
~_after=?,
~_even=?,
~_odd=?,
~_first=?,
~_last=?,
~_notFirst=?,
~_notLast=?,
~transition=?,
~transitionProperty=?,
~transitionDelay=?,
~transitionDuration=?,
~transitionTimingFunction=?,
~transitions=?,
// declaration:end
// React props
~children=?,
~dangerouslySetInnerHTML=?,
~innerRef=?,
// DOM Props
~className="",
~tag: Ancestor_React.tags=#div,
~id=?,
~onClick=?,
~onSubmit=?,
~onChange=?,
~src=?,
~alt=?,
~ariaDetails=?,
~ariaDisabled=?,
~ariaHidden=?,
~ariaKeyshortcuts=?,
~ariaLabel=?,
~ariaRoledescription=?,
~ariaExpanded=?,
~ariaLevel=?,
~ariaModal=?,
~ariaMultiline=?,
~ariaMultiselectable=?,
~ariaPlaceholder=?,
~ariaReadonly=?,
~ariaRequired=?,
~ariaSelected=?,
~ariaSort=?,
~ariaValuemax=?,
~ariaValuemin=?,
~ariaValuenow=?,
~ariaValuetext=?,
~ariaAtomic=?,
~ariaBusy=?,
~ariaRelevant=?,
~ariaGrabbed=?,
~ariaActivedescendant=?,
~ariaColcount=?,
~ariaColindex=?,
~ariaColspan=?,
~ariaControls=?,
~ariaDescribedby=?,
~ariaErrormessage=?,
~ariaFlowto=?,
~ariaLabelledby=?,
~ariaOwns=?,
~ariaPosinset=?,
~ariaRowcount=?,
~ariaRowindex=?,
~ariaRowspan=?,
~ariaSetsize=?,
~defaultChecked=?,
~defaultValue=?,
~accessKey=?,
~contentEditable=?,
~contextMenu=?,
~lang=?,
~role=?,
~style=?,
~spellCheck=?,
~tabIndex=?,
~title=?,
~itemID=?,
~itemProp=?,
~itemRef=?,
~itemScope=?,
~itemType=?,
~accept=?,
~acceptCharset=?,
~action=?,
~allowFullScreen=?,
~async=?,
~autoComplete=?,
~autoCapitalize=?,
~autoFocus=?,
~autoPlay=?,
~challenge=?,
~charSet=?,
~checked=?,
~cite=?,
~crossOrigin=?,
~cols=?,
~colSpan=?,
~content=?,
~controls=?,
~coords=?,
~data=?,
~dateTime=?,
~default=?,
~defer=?,
~disabled=?,
~download=?,
~encType=?,
~form=?,
~formAction=?,
~formTarget=?,
~formMethod=?,
~headers=?,
~high=?,
~href=?,
~hrefLang=?,
~htmlFor=?,
~httpEquiv=?,
~icon=?,
~inputMode=?,
~integrity=?,
~keyType=?,
~kind=?,
~label=?,
~list=?,
~loop=?,
~low=?,
~manifest=?,
~max=?,
~maxLength=?,
~media=?,
~mediaGroup=?,
~method=?,
~min=?,
~minLength=?,
~multiple=?,
~muted=?,
~name=?,
~nonce=?,
~noValidate=?,
~open_=?,
~optimum=?,
~pattern=?,
~placeholder=?,
~playsInline=?,
~poster=?,
~preload=?,
~radioGroup=?,
~readOnly=?,
~rel=?,
~required=?,
~reversed=?,
~rows=?,
~rowSpan=?,
~sandbox=?,
~scope=?,
~scoped=?,
~scrolling=?,
~selected=?,
~shape=?,
~size=?,
~sizes=?,
~span=?,
~srcDoc=?,
~srcLang=?,
~srcSet=?,
~start=?,
~step=?,
~summary=?,
~target=?,
~type_=?,
~useMap=?,
~value=?,
~wrap=?,
~onCopy=?,
~onCut=?,
~onPaste=?,
~onCompositionEnd=?,
~onCompositionStart=?,
~onCompositionUpdate=?,
~onKeyDown=?,
~onKeyPress=?,
~onKeyUp=?,
~onFocus=?,
~onBlur=?,
~onInput=?,
~onInvalid=?,
~onContextMenu=?,
~onDoubleClick=?,
~onDrag=?,
~onDragEnd=?,
~onDragEnter=?,
~onDragExit=?,
~onDragLeave=?,
~onDragOver=?,
~onDragStart=?,
~onDrop=?,
~onMouseDown=?,
~onMouseEnter=?,
~onMouseLeave=?,
~onMouseMove=?,
~onMouseOut=?,
~onMouseOver=?,
~onMouseUp=?,
~onSelect=?,
~onTouchCancel=?,
~onTouchEnd=?,
~onTouchMove=?,
~onTouchStart=?,
~onPointerOver=?,
~onPointerEnter=?,
~onPointerDown=?,
~onPointerMove=?,
~onPointerUp=?,
~onPointerCancel=?,
~onPointerOut=?,
~onPointerLeave=?,
~onGotPointerCapture=?,
~onLostPointerCapture=?,
~onScroll=?,
~onWheel=?,
~onAbort=?,
~onCanPlay=?,
~onCanPlayThrough=?,
~onDurationChange=?,
~onEmptied=?,
~onEnded=?,
~onError=?,
~onLoadedData=?,
~onLoadedMetadata=?,
~onLoadStart=?,
~onPause=?,
~onPlay=?,
~onPlaying=?,
~onProgress=?,
~onRateChange=?,
~onSeeked=?,
~onSeeking=?,
~onStalled=?,
~onSuspend=?,
~onTimeUpdate=?,
~onVolumeChange=?,
~onWaiting=?,
~onLoad=?,
~onAnimationStart=?,
~onAnimationEnd=?,
~onAnimationIteration=?,
~onTransitionEnd=?,
) => {
}
}
================================================
FILE: packages/core/src/components/hidden/Ancestor_Hidden_Stories.res
================================================
open Ancestor
open Ancestor_Helpers
let default = Storybook.story(~title="Components/Hidden", ())
let basicUsage = () => {
#px}> {"Only visible above md"->React.string}
#px}> {"Only visible below md"->React.string}
}
================================================
FILE: packages/core/src/components/stack/Ancestor_Stack.res
================================================
module Make = (Config: Ancestor_Config.T) => {
module Styles = Ancestor_Styles.Make(Config)
module Base = Ancestor_Base.Make(Config)
type direction = [
| #vertical
| #horizontal
]
/**
* Specific styles for the API.
*/
module LocalStyles = {
open Styles.Css
let baseStyles = [display(#flex)]
let createStack = (~direction=?, ()) => {
let directionStyles = Styles.createResponsiveProp(
~prop=direction,
~defaultStyles=[flexDirection(#column)],
direction =>
switch direction {
| #vertical => [flexDirection(#column)]
| #horizontal => [flexDirection(#row)]
},
)
let styles = Belt.Array.concatMany([baseStyles, directionStyles])
style(. styles)
}
}
let renderWithDivider = (children, divider) => {
let total = React.Children.count(children)
children->React.Children.mapWithIndex((element, index) => {
if index == total - 1 {
element
} else {
<>
element
divider
>
}
})
}
@react.component
let make = (
// Stack props
~direction: option>=?,
~divider: option=?,
// declaration:start
~borderRadius=?,
~borderTLRadius=?,
~borderTRRadius=?,
~borderBLRadius=?,
~borderBRRadius=?,
~borderStyle=?,
~borderColor=?,
~borderWidth=?,
~borderRightStyle=?,
~borderLeftStyle=?,
~borderTopStyle=?,
~borderBottomStyle=?,
~borderRightColor=?,
~borderLeftColor=?,
~borderTopColor=?,
~borderBottomColor=?,
~borderRightWidth=?,
~borderLeftWidth=?,
~borderTopWidth=?,
~borderBottomWidth=?,
~border=?,
~borderRight=?,
~borderLeft=?,
~borderTop=?,
~borderBottom=?,
~bgColor=?,
~bgSize=?,
~bgPosition=?,
~bgImage=?,
~color=?,
~display=?,
~justifyContent=?,
~flexDirection=?,
~alignItems=?,
~flexBasis=?,
~flexWrap=?,
~flexGrow=?,
~alignContent=?,
~alignSelf=?,
~justifySelf=?,
~gap=?,
~p=?,
~px=?,
~py=?,
~pt=?,
~pb=?,
~pl=?,
~pr=?,
~m=?,
~mx=?,
~my=?,
~mt=?,
~mb=?,
~ml=?,
~mr=?,
~textAlign=?,
~fontFamily=?,
~fontWeight=?,
~fontSize=?,
~letterSpacing=?,
~lineHeight=?,
~width=?,
~height=?,
~minW=?,
~minH=?,
~maxW=?,
~maxH=?,
~position=?,
~top=?,
~bottom=?,
~left=?,
~right=?,
~zIndex=?,
~boxSizing=?,
~overflow=?,
~overflowX=?,
~overflowY=?,
~cursor=?,
~visibility=?,
~listStyleType=?,
~listStylePosition=?,
~listStyleImage=?,
~listStyle=?,
~outlineStyle=?,
~outline=?,
~textDecorationStyle=?,
~textDecorationLine=?,
~textDecoration=?,
~transform=?,
~_hover=?,
~_focus=?,
~_active=?,
~_focusWithin=?,
~_focusVisible=?,
~_disabled=?,
~_before=?,
~_after=?,
~_even=?,
~_odd=?,
~_first=?,
~_last=?,
~_notFirst=?,
~_notLast=?,
~transition=?,
~transitionProperty=?,
~transitionDelay=?,
~transitionDuration=?,
~transitionTimingFunction=?,
~transitions=?,
// declaration:end
// React props
~children=?,
~dangerouslySetInnerHTML=?,
~innerRef=?,
// DOM Props
~className="",
~tag: Ancestor_React.tags=#div,
~id=?,
~onClick=?,
~onSubmit=?,
~onChange=?,
~src=?,
~alt=?,
~ariaDetails=?,
~ariaDisabled=?,
~ariaHidden=?,
~ariaKeyshortcuts=?,
~ariaLabel=?,
~ariaRoledescription=?,
~ariaExpanded=?,
~ariaLevel=?,
~ariaModal=?,
~ariaMultiline=?,
~ariaMultiselectable=?,
~ariaPlaceholder=?,
~ariaReadonly=?,
~ariaRequired=?,
~ariaSelected=?,
~ariaSort=?,
~ariaValuemax=?,
~ariaValuemin=?,
~ariaValuenow=?,
~ariaValuetext=?,
~ariaAtomic=?,
~ariaBusy=?,
~ariaRelevant=?,
~ariaGrabbed=?,
~ariaActivedescendant=?,
~ariaColcount=?,
~ariaColindex=?,
~ariaColspan=?,
~ariaControls=?,
~ariaDescribedby=?,
~ariaErrormessage=?,
~ariaFlowto=?,
~ariaLabelledby=?,
~ariaOwns=?,
~ariaPosinset=?,
~ariaRowcount=?,
~ariaRowindex=?,
~ariaRowspan=?,
~ariaSetsize=?,
~defaultChecked=?,
~defaultValue=?,
~accessKey=?,
~contentEditable=?,
~contextMenu=?,
~lang=?,
~role=?,
~style=?,
~spellCheck=?,
~tabIndex=?,
~title=?,
~itemID=?,
~itemProp=?,
~itemRef=?,
~itemScope=?,
~itemType=?,
~accept=?,
~acceptCharset=?,
~action=?,
~allowFullScreen=?,
~async=?,
~autoComplete=?,
~autoCapitalize=?,
~autoFocus=?,
~autoPlay=?,
~challenge=?,
~charSet=?,
~checked=?,
~cite=?,
~crossOrigin=?,
~cols=?,
~colSpan=?,
~content=?,
~controls=?,
~coords=?,
~data=?,
~dateTime=?,
~default=?,
~defer=?,
~disabled=?,
~download=?,
~encType=?,
~form=?,
~formAction=?,
~formTarget=?,
~formMethod=?,
~headers=?,
~high=?,
~href=?,
~hrefLang=?,
~htmlFor=?,
~httpEquiv=?,
~icon=?,
~inputMode=?,
~integrity=?,
~keyType=?,
~kind=?,
~label=?,
~list=?,
~loop=?,
~low=?,
~manifest=?,
~max=?,
~maxLength=?,
~media=?,
~mediaGroup=?,
~method=?,
~min=?,
~minLength=?,
~multiple=?,
~muted=?,
~name=?,
~nonce=?,
~noValidate=?,
~open_=?,
~optimum=?,
~pattern=?,
~placeholder=?,
~playsInline=?,
~poster=?,
~preload=?,
~radioGroup=?,
~readOnly=?,
~rel=?,
~required=?,
~reversed=?,
~rows=?,
~rowSpan=?,
~sandbox=?,
~scope=?,
~scoped=?,
~scrolling=?,
~selected=?,
~shape=?,
~size=?,
~sizes=?,
~span=?,
~srcDoc=?,
~srcLang=?,
~srcSet=?,
~start=?,
~step=?,
~summary=?,
~target=?,
~type_=?,
~useMap=?,
~value=?,
~wrap=?,
~onCopy=?,
~onCut=?,
~onPaste=?,
~onCompositionEnd=?,
~onCompositionStart=?,
~onCompositionUpdate=?,
~onKeyDown=?,
~onKeyPress=?,
~onKeyUp=?,
~onFocus=?,
~onBlur=?,
~onInput=?,
~onInvalid=?,
~onContextMenu=?,
~onDoubleClick=?,
~onDrag=?,
~onDragEnd=?,
~onDragEnter=?,
~onDragExit=?,
~onDragLeave=?,
~onDragOver=?,
~onDragStart=?,
~onDrop=?,
~onMouseDown=?,
~onMouseEnter=?,
~onMouseLeave=?,
~onMouseMove=?,
~onMouseOut=?,
~onMouseOver=?,
~onMouseUp=?,
~onSelect=?,
~onTouchCancel=?,
~onTouchEnd=?,
~onTouchMove=?,
~onTouchStart=?,
~onPointerOver=?,
~onPointerEnter=?,
~onPointerDown=?,
~onPointerMove=?,
~onPointerUp=?,
~onPointerCancel=?,
~onPointerOut=?,
~onPointerLeave=?,
~onGotPointerCapture=?,
~onLostPointerCapture=?,
~onScroll=?,
~onWheel=?,
~onAbort=?,
~onCanPlay=?,
~onCanPlayThrough=?,
~onDurationChange=?,
~onEmptied=?,
~onEnded=?,
~onError=?,
~onLoadedData=?,
~onLoadedMetadata=?,
~onLoadStart=?,
~onPause=?,
~onPlay=?,
~onPlaying=?,
~onProgress=?,
~onRateChange=?,
~onSeeked=?,
~onSeeking=?,
~onStalled=?,
~onSuspend=?,
~onTimeUpdate=?,
~onVolumeChange=?,
~onWaiting=?,
~onLoad=?,
~onAnimationStart=?,
~onAnimationEnd=?,
~onAnimationIteration=?,
~onTransitionEnd=?,
) => {
{switch (children, divider) {
| (None, None) => React.null
| (Some(children), None) => children
| (None, Some(divider)) => divider
| (Some(children), Some(divider)) => renderWithDivider(children, divider)
}}
}
}
================================================
FILE: packages/core/src/components/stack/Ancestor_Stack_Stories.res
================================================
open Ancestor
open Ancestor_Helpers
let default = Storybook.story(~title="Components/Stack", ())
let \"BasicUsage" = () => {
#rem}
p={xs: 2}
borderRadius={xs: 1}
border={xs: (2->#px, #solid, Colors.gray1)}
direction={xs: #horizontal}
gap={xs: 2, md: 4}>
#percent} />
#percent} />
#percent} />
}
let \"WithDivider" = () => {
#px, #solid, Colors.gray1)}
divider={ #px} width={md: 2.4->#rem} bgColor={xs: #hex("#000")} />}
direction={xs: #horizontal, md: #vertical}
gap={xs: 2, md: 4}>
#percent, md: 7.2->#rem} />
#percent, md: 7.2->#rem} />
#percent, md: 7.2->#rem} />
}
================================================
FILE: packages/core/src/core/Ancestor_Config.res
================================================
/*
* NOTE: The breakpoint module used to create the custom breakpoints API.
*/
module type Breakpoints = {
type breakpoints<'value>
type keyOfBreakpoints
let encode: breakpoints<'value> => array<(keyOfBreakpoints, option<'value>)>
let sizeByBreakpoints: keyOfBreakpoints => int
}
module type T = {
type breakpoints<'value>
type keyOfBreakpoints
type spacing
type radius
type colors
type zIndex
type fontFamily
type fontSize
type fontWeight
type lineHeight
type letterSpacing
type textShadow
type boxShadow
let encode: breakpoints<'value> => array<(keyOfBreakpoints, option<'value>)>
let zIndex: zIndex => int
let colors: colors => AncestorCss_WrappedTypes.Color.t
let spacing: spacing => Css_AtomicTypes.Length.t
let radius: radius => Css_AtomicTypes.Length.t
let sizeByBreakpoints: keyOfBreakpoints => int
let fontFamily: fontFamily => AncestorCss_WrappedTypes.FontFamily.t
let fontSize: fontSize => Css_AtomicTypes.Length.t
let fontWeight: fontWeight => Css_AtomicTypes.FontWeight.t
let lineHeight: lineHeight => AncestorCss_WrappedTypes.LineHeight.t
let letterSpacing: letterSpacing => Css_AtomicTypes.Length.t
let textShadow: textShadow => AncestorCss_WrappedTypes.TextShadow.t
let boxShadow: boxShadow => AncestorCss_WrappedTypes.BoxShadow.t
}
================================================
FILE: packages/core/src/core/Ancestor_Core.res
================================================
module Make = (
BreakpointsConfig: Ancestor_Config.Breakpoints,
ColorsConfig: AncestorCss_Config.Colors,
SpacingConfig: AncestorCss_Config.Spacing,
RadiusConfig: AncestorCss_Config.Radius,
ZIndexConfig: AncestorCss_Config.ZIndex,
TypographyConfig: AncestorCss_Config.Typography,
ShadowsConfig: AncestorCss_Config.Shadows,
) => {
module Config__Internal = {
include BreakpointsConfig
include ColorsConfig
include SpacingConfig
include RadiusConfig
include ZIndexConfig
include TypographyConfig
include ShadowsConfig
}
module Styles = Ancestor_Styles.Make(Config__Internal)
/**
* Components
*/
module Base = Ancestor_Base.Make(Config__Internal)
module Box = Ancestor_Box.Make(Config__Internal)
module Grid = Ancestor_Grid.Make(Config__Internal)
module Hidden = Ancestor_Hidden.Make(Config__Internal)
module Stack = Ancestor_Stack.Make(Config__Internal)
module Typography = Base
module Css = Styles.Css
module ResponsiveValueHook = Ancestor_ResponsiveValueHook.Make(Config__Internal)
/**
* Exposing Ancestor hooks
*/
let {useResponsiveValue} = module(ResponsiveValueHook)
}
================================================
FILE: packages/core/src/core/Ancestor_Styles.res
================================================
module Make = (Config: Ancestor_Config.T) => {
module Css = AncestorCss.Make(
{
type breakpoints = Config.keyOfBreakpoints
let sizeByBreakpoints = Config.sizeByBreakpoints
},
{
type colors = Config.colors
let colors = Config.colors
},
{
type spacing = Config.spacing
let spacing = Config.spacing
},
{
type radius = Config.radius
let radius = Config.radius
},
{
type zIndex = Config.zIndex
let zIndex = Config.zIndex
},
{
type fontFamily = Config.fontFamily
type fontSize = Config.fontSize
type fontWeight = Config.fontWeight
type lineHeight = Config.lineHeight
type letterSpacing = Config.letterSpacing
let fontFamily = Config.fontFamily
let fontSize = Config.fontSize
let fontWeight = Config.fontWeight
let lineHeight = Config.lineHeight
let letterSpacing = Config.letterSpacing
},
{
type boxShadow = Config.boxShadow
type textShadow = Config.textShadow
let boxShadow = Config.boxShadow
let textShadow = Config.textShadow
},
)
let filterEmptyValues = values =>
values->Js.Array2.reduce((values, (breakpointName, breakpointValue)) => {
switch breakpointValue {
| None => values
| Some(breakpointValue) => values->Js.Array2.concat([(breakpointName, breakpointValue)])
}
}, [])
let sortBySize = ((first, _), (second, _)) => {
Config.sizeByBreakpoints(first) - Config.sizeByBreakpoints(second)
}
let createResponsiveProp = (~prop, ~defaultStyles=[], transform) => {
switch prop {
| None => defaultStyles
| Some(values) =>
values
->Config.encode
->filterEmptyValues
->Js.Array2.sortInPlaceWith(sortBySize)
->Js.Array2.reduce(
(currentStyles, (breakpoint, value)) =>
currentStyles->Js.Array2.concat([Css.breakpoint(breakpoint, transform(value))]),
[],
)
}
}
module RulesCmp = Belt.Id.MakeComparable({
type t = Config.keyOfBreakpoints
let cmp = (a, b) => Pervasives.compare(a, b)
})
let groupRulesByBreakpoint = (transformValue, mapper, (breakpoint, maybeValue)) =>
maybeValue
->Belt.Option.map(transformValue)
->Belt.Option.map(v => [v])
->Belt.Option.map(rules =>
switch mapper->Belt.Map.get(breakpoint) {
| None => mapper->Belt.Map.set(breakpoint, rules)
| Some(existingRules) => {
let updatedRules = existingRules->Js.Array2.concat(rules)
mapper->Belt.Map.set(breakpoint, updatedRules)
}
}
)
->Belt.Option.getWithDefault(mapper)
let addRule = (mapper, transformValue, maybeValues) =>
maybeValues
->Belt.Option.map(Config.encode)
->Belt.Option.map(values =>
values->Js.Array2.reduce(groupRulesByBreakpoint(transformValue), mapper)
)
->Belt.Option.getWithDefault(mapper)
let mergeRulesByBreakpoint = values => values->Js.Array2.reduce((styles, (breakpoint, rules)) =>
switch rules {
| None => styles
| Some(rules) => {
let breakpointStyles = Css.breakpoint(breakpoint, rules)
styles->Js.Array2.concat([breakpointStyles])
}
}
, [])
let createSelector = (selectorValue, maybeValues) =>
maybeValues
->Belt.Option.map(Config.encode)
->Belt.Option.map(mergeRulesByBreakpoint)
->Belt.Option.map(values => Css.selector(. selectorValue, values))
let createPseudoSelector = (selector, maybeValues) =>
maybeValues
->Belt.Option.map(Config.encode)
->Belt.Option.map(mergeRulesByBreakpoint)
->Belt.Option.map(selector)
let removeOptionals = items => items->Js.Array2.reduce((acc, current) =>
switch current {
| None => acc
| Some(item) => acc->Js.Array2.concat([item])
}
, [])
let createResponsiveStyles = (
~borderRadius=?,
~borderTLRadius=?,
~borderTRRadius=?,
~borderBLRadius=?,
~borderBRRadius=?,
~borderStyle=?,
~borderColor=?,
~borderWidth=?,
~borderRightStyle=?,
~borderLeftStyle=?,
~borderTopStyle=?,
~borderBottomStyle=?,
~borderRightColor=?,
~borderLeftColor=?,
~borderTopColor=?,
~borderBottomColor=?,
~borderRightWidth=?,
~borderLeftWidth=?,
~borderTopWidth=?,
~borderBottomWidth=?,
~border=?,
~borderRight=?,
~borderLeft=?,
~borderTop=?,
~borderBottom=?,
~bgColor=?,
~bgSize=?,
~bgPosition=?,
~bgImage=?,
~color=?,
~display=?,
~justifyContent=?,
~flexDirection=?,
~alignItems=?,
~flexBasis=?,
~flexWrap=?,
~flexGrow=?,
~alignContent=?,
~alignSelf=?,
~justifySelf=?,
~gap=?,
~p=?,
~py=?,
~px=?,
~pt=?,
~pb=?,
~pl=?,
~pr=?,
~m=?,
~mx=?,
~my=?,
~mt=?,
~mb=?,
~ml=?,
~mr=?,
~textAlign=?,
~fontFamily=?,
~fontWeight=?,
~fontSize=?,
~letterSpacing=?,
~lineHeight=?,
~width=?,
~height=?,
~minW=?,
~minH=?,
~maxW=?,
~maxH=?,
~position=?,
~top=?,
~bottom=?,
~left=?,
~right=?,
~zIndex=?,
~boxSizing=?,
~overflow=?,
~overflowX=?,
~overflowY=?,
~cursor=?,
~visibility=?,
~listStyleType=?,
~listStylePosition=?,
~listStyleImage=?,
~listStyle=?,
~outlineStyle=?,
~outline=?,
~textDecorationStyle=?,
~textDecorationLine=?,
~textDecoration=?,
~transform=?,
// Support for transition
~transition=?,
~transitionProperty=?,
~transitionDelay=?,
~transitionDuration=?,
~transitionTimingFunction=?,
~transitions=?,
// Support for pseudo
~_hover=?,
~_focus=?,
~_active=?,
~_focusWithin=?,
~_focusVisible=?,
~_disabled=?,
~_before=?,
~_after=?,
~_even=?,
~_odd=?,
~_first=?,
~_last=?,
~_notFirst=?,
~_notLast=?,
(),
) => {
let ps = createPseudoSelector
let cs = createSelector
let rules =
Belt.Map.make(~id=module(RulesCmp))
->addRule(Css.color, color)
->addRule(Css.backgroundColor, bgColor)
// Margin
->addRule(Css.margin, m)
->addRule(Css.marginBottom, my)
->addRule(Css.marginTop, my)
->addRule(Css.marginRight, mx)
->addRule(Css.marginLeft, mx)
->addRule(Css.marginTop, mt)
->addRule(Css.marginBottom, mb)
->addRule(Css.marginRight, mr)
->addRule(Css.marginLeft, ml)
// Padding
->addRule(Css.padding, p)
->addRule(Css.paddingBottom, py)
->addRule(Css.paddingTop, py)
->addRule(Css.paddingRight, px)
->addRule(Css.paddingLeft, px)
->addRule(Css.paddingTop, pt)
->addRule(Css.paddingBottom, pb)
->addRule(Css.paddingRight, pr)
->addRule(Css.paddingLeft, pl)
->addRule(Css.zIndex, zIndex)
// Border Radius
->addRule(Css.borderRadius, borderRadius)
->addRule(Css.borderTopLeftRadius, borderTLRadius)
->addRule(Css.borderTopRightRadius, borderTRRadius)
->addRule(Css.borderBottomLeftRadius, borderBLRadius)
->addRule(Css.borderBottomRightRadius, borderBRRadius)
// Border
->addRule(Css.borderStyle, borderStyle)
->addRule(Css.borderColor, borderColor)
->addRule(Css.borderWidth, borderWidth)
->addRule(Css.borderRightStyle, borderRightStyle)
->addRule(Css.borderLeftStyle, borderLeftStyle)
->addRule(Css.borderTopStyle, borderTopStyle)
->addRule(Css.borderBottomStyle, borderBottomStyle)
->addRule(Css.borderRightColor, borderRightColor)
->addRule(Css.borderLeftColor, borderLeftColor)
->addRule(Css.borderTopColor, borderTopColor)
->addRule(Css.borderBottomColor, borderBottomColor)
->addRule(Css.borderRightWidth, borderRightWidth)
->addRule(Css.borderLeftWidth, borderLeftWidth)
->addRule(Css.borderTopWidth, borderTopWidth)
->addRule(Css.borderBottomWidth, borderBottomWidth)
->addRule(((size, style, color)) => Css.border(size, style, color), border)
->addRule(((size, style, color)) => Css.borderRight(size, style, color), borderRight)
->addRule(((size, style, color)) => Css.borderLeft(size, style, color), borderLeft)
->addRule(((size, style, color)) => Css.borderTop(size, style, color), borderTop)
->addRule(((size, style, color)) => Css.borderBottom(size, style, color), borderBottom)
->addRule(Css.backgroundSize, bgSize)
->addRule(Css.backgroundPosition, bgPosition)
->addRule(Css.backgroundImage, bgImage)
// Flex
->addRule(Css.display, display)
->addRule(Css.justifyContent, justifyContent)
->addRule(Css.flexDirection, flexDirection)
->addRule(Css.alignItems, alignItems)
->addRule(Css.flexBasis, flexBasis)
->addRule(Css.flexWrap, flexWrap)
->addRule(Css.flexGrow, flexGrow)
->addRule(Css.alignContent, alignContent)
->addRule(Css.alignSelf, alignSelf)
->addRule(Css.justifySelf, justifySelf)
->addRule(Css.gap, gap)
// Others
->addRule(Css.textAlign, textAlign)
->addRule(Css.fontFamily, fontFamily)
->addRule(Css.fontWeight, fontWeight)
->addRule(Css.fontSize, fontSize)
->addRule(Css.letterSpacing, letterSpacing)
->addRule(Css.lineHeight, lineHeight)
->addRule(Css.width, width)
->addRule(Css.height, height)
->addRule(Css.minWidth, minW)
->addRule(Css.minHeight, minH)
->addRule(Css.maxWidth, maxW)
->addRule(Css.maxHeight, maxH)
->addRule(Css.position, position)
->addRule(Css.top, top)
->addRule(Css.bottom, bottom)
->addRule(Css.left, left)
->addRule(Css.right, right)
->addRule(Css.boxSizing, boxSizing)
->addRule(Css.overflow, overflow)
->addRule(Css.overflowX, overflowX)
->addRule(Css.overflowY, overflowY)
->addRule(Css.cursor, cursor)
->addRule(Css.visibility, visibility)
->addRule(Css.listStyleType, listStyleType)
->addRule(Css.listStylePosition, listStylePosition)
->addRule(Css.listStyleImage, listStyleImage)
->addRule(((type_, position, image)) => Css.listStyle(type_, position, image), listStyle)
->addRule(Css.outlineStyle, outlineStyle)
->addRule(((size, style, color)) => Css.outline(size, style, color), outline)
->addRule(Css.textDecorationStyle, textDecorationStyle)
->addRule(Css.textDecorationLine, textDecorationLine)
->addRule(Css.textDecoration, textDecoration)
->addRule(Css.transform, transform)
->addRule(Css.transitionValue, transition)
->addRule(Css.transitionProperty, transitionProperty)
->addRule(Css.transitionDelay, transitionDelay)
->addRule(Css.transitionDuration, transitionDuration)
->addRule(Css.transitionTimingFunction, transitionTimingFunction)
->addRule(Css.transitions, transitions)
let pseudoSelectorsRules =
[
ps(Css.hover, _hover),
ps(Css.hover, _hover),
ps(Css.focus, _focus),
ps(Css.active, _active),
ps(Css.focusWithin, _focusWithin),
ps(Css.focusVisible, _focusVisible),
ps(Css.disabled, _disabled),
ps(Css.before, _before),
ps(Css.after, _after),
ps(Css.first, _first),
cs("&:nth-of-type(even)", _even),
cs("&:nth-of-type(odd)", _odd),
cs("&:last-of-type", _last),
cs("&:not(:first-of-type)", _notFirst),
cs("&:not(:last-of-type)", _notLast),
]->removeOptionals
let parsedRules =
rules
->Belt.Map.toArray
->Js.Array2.sortInPlaceWith(sortBySize)
->Js.Array2.map(((breakpoint, rules)) => Css.breakpoint(breakpoint, rules))
->Js.Array2.concat(pseudoSelectorsRules)
Css.style(. parsedRules)
}
}
================================================
FILE: packages/core/src/hooks/Ancestor_ResponsiveValueHook.res
================================================
module Make = (Config: Ancestor_Config.T) => {
module Styles = Ancestor_Styles.Make(Config)
@val @scope("globalThis") external window: option = "window"
@get external innerWidth: Dom.window => float = "innerWidth"
@send external addEventListener: (Dom.window, string, unit => unit) => unit = "addEventListener"
@send
external removeEventListener: (Dom.window, string, unit => unit) => unit = "removeEventListener"
let initialWidth = window->Belt.Option.map(w => w->innerWidth)
let getBreakpointValue = (innerWidth, values: Config.breakpoints<'a>) =>
values
->Config.encode
->Styles.filterEmptyValues
->Js.Array2.reduce((acc, (breakpoint, value)) => {
let breakpoint = breakpoint->Config.sizeByBreakpoints
if innerWidth >= breakpoint->Js.Int.toFloat {
Some(value)
} else {
acc
}
}, None)
let useResponsiveValue = (default, values) => {
let (width, setWidth) = React.useState(_ => initialWidth)
React.useEffect0(() => {
let updateWidth = () => setWidth(_ => window->Belt.Option.map(w => w->innerWidth))
window->Belt.Option.map(w => w->addEventListener("resize", updateWidth))->ignore
Some(
() => window->Belt.Option.map(w => w->removeEventListener("resize", updateWidth))->ignore,
)
})
width
->Belt.Option.flatMap(width => getBreakpointValue(width, values))
->Belt.Option.getWithDefault(default)
}
}
================================================
FILE: packages/core/src/hooks/Ancestor_ResponsiveValueHook_Stories.res
================================================
let default = Storybook.story(~title="Hooks/useResponsiveValue", ~excludeStories=["Card"], ())
open Ancestor
module Card = {
@react.component
let make = (~color, ~label) =>
#px} color={xs: "#fafafa"->#hex} bgColor={xs: color}>
{label->React.string}
}
let basicUsage = () => {
let color = Ancestor.useResponsiveValue("000"->#hex, {xs: "000"->#hex, md: "716e6e"->#hex})
let label = Ancestor.useResponsiveValue(
"Default",
{xs: "Mobile", sm: "Small", md: "Tablet", lg: "Large", xl: "Extra Large"},
)
}
================================================
FILE: packages/css/.npmignore
================================================
*_Stories.res
*_Test.res
__tests__/
src/_helpers_/
**/__snapshots__/
.storybook
================================================
FILE: packages/css/.storybook/main.js
================================================
module.exports = {
stories: ["../src/**/*_Stories.bs.js"],
addons: [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions",
],
framework: "@storybook/react",
};
================================================
FILE: packages/css/.storybook/preview-head.html
================================================
================================================
FILE: packages/css/.storybook/preview.js
================================================
export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
}
================================================
FILE: packages/css/__tests__/AncestorCss_Custom.res
================================================
include AncestorCss.Make(
{
type breakpoints = [#xs | #sm]
let sizeByBreakpoints = v =>
switch v {
| #xs => 0
| #sm => 470
}
},
{
type colors = [#primary | #secondary]
let colors = (x: colors) =>
switch x {
| #primary => #hex("fc0")
| #secondary => #hex("363636")
}
},
AncestorCss.Defaults.Spacing,
AncestorCss.Defaults.Radius,
AncestorCss.Defaults.ZIndex,
AncestorCss.Defaults.Typography,
AncestorCss.Defaults.Shadows,
)
================================================
FILE: packages/css/__tests__/AncestorCss_Test.res
================================================
open Jest
open Expect
module Renderer = ReactTestRenderer
describe("Tokens", () => {
test("should transform spacing tokens correctly", () => {
open AncestorCss_Custom
let className = style(. [padding(2), margin(4)])
expect(Renderer.create(
)->Renderer.toJSON)->toMatchSnapshot
})
test("should transform color tokens correctly", () => {
open AncestorCss_Custom
let className = style(. [color(#primary), bgColor(#secondary)])
expect(Renderer.create(
)->Renderer.toJSON)->toMatchSnapshot
})
})
================================================
FILE: packages/css/__tests__/__snapshots__/AncestorCss_Test.bs.js.snap
================================================
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Tokens should transform color tokens correctly 1`] = `
.emotion-0 {
color: #fc0;
background-color: #363636;
}
`;
exports[`Tokens should transform spacing tokens correctly 1`] = `
.emotion-0 {
padding: 16px;
margin: 32px;
}
`;
================================================
FILE: packages/css/bsconfig.json
================================================
{
"name": "@ancestor-ui/css",
"version": "0.0.1",
"sources": [
{
"dir": "__tests__",
"type": "dev",
"subdirs": true
},
{
"dir": "src",
"subdirs": true
}
],
"package-specs": [
{
"module": "commonjs",
"in-source": true
}
],
"jsx": { "version": 4, "mode": "classic" },
"suffix": ".bs.js",
"bs-dependencies": [
"@rescript/react",
"@ancestor-ui/bindings",
"bs-css",
"bs-css-emotion"
],
"bs-dev-dependencies": [
"@greenlabs/rescript-jest",
"@greenlabs/rescript-testing-library"
],
"ppx-flags": []
}
================================================
FILE: packages/css/jest.config.js
================================================
module.exports = {
testMatch: ["**/*_Test.bs.js"],
snapshotSerializers: ["@emotion/jest/serializer"],
testEnvironment: "jsdom",
};
================================================
FILE: packages/css/package.json
================================================
{
"name": "@ancestor-ui/css",
"version": "0.6.1",
"main": "index.js",
"license": "MIT",
"devDependencies": {
"@babel/core": "7.20.5",
"@emotion/css": "11.10.0",
"@emotion/jest": "11.9.3",
"@greenlabs/rescript-jest": "1.0.1",
"@greenlabs/rescript-testing-library": "2.0.1",
"@rescript/react": "0.11.0-rc.3",
"@storybook/addon-actions": "6.5.15",
"@storybook/addon-essentials": "6.5.15",
"@storybook/addon-interactions": "6.5.15",
"@storybook/addon-links": "6.5.15",
"@storybook/builder-webpack4": "6.5.15",
"@storybook/manager-webpack4": "6.5.15",
"@storybook/react": "6.5.15",
"@storybook/testing-library": "0.0.13",
"babel-loader": "8.3.0",
"jest": "29.3.1",
"jest-environment-jsdom": "29.3.1",
"jsdom": "20.0.3",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-test-renderer": "18.2.0",
"rescript": "10.1.0"
},
"peerDependencies": {
"@rescript/react": ">=0.11",
"react": ">=18",
"react-dom": ">=18",
"rescript": ">=10"
},
"dependencies": {
"@ancestor-ui/bindings": "0.1.0",
"bs-css": "16.0.0",
"bs-css-emotion": "5.0.0",
"rescript-webapi": "0.7.0"
},
"scripts": {
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook",
"test": "jest"
}
}
================================================
FILE: packages/css/spec.md
================================================
## CSS Spec
- [ ] transition
- [ ] keyframes
- [ ] animation
- [ ] box-shadow
================================================
FILE: packages/css/src/AncestorCss.res
================================================
/*
* NOTE: AncestorCss defaults.
*/
module Defaults = {
let identity = v => v
module Breakpoints = {
type breakpoints = [#xs | #sm | #md | #lg | #xl]
let sizeByBreakpoints = breakpoint =>
switch breakpoint {
| #xs => 0
| #sm => 475
| #md => 920
| #lg => 1280
| #xl => 1920
}
}
module Colors = {
type colors = AncestorCss_WrappedTypes.Color.t
let colors = identity
}
module Spacing = {
type spacing = int
let spacing = v => #px(v * 8)
}
module Radius = {
type radius = int
let radius = v => #px(v * 8)
}
module ZIndex = {
type zIndex = int
let zIndex = identity
}
module FontSize = {
type fontSize = Css_AtomicTypes.Length.t
let fontSize = identity
}
module FontFamily = {
type fontFamily = AncestorCss_WrappedTypes.FontFamily.t
let fontFamily = identity
}
module FontWeight = {
type fontWeight = Css_AtomicTypes.FontWeight.t
let fontWeight = identity
}
module LineHeight = {
type lineHeight = AncestorCss_WrappedTypes.LineHeight.t
let lineHeight = identity
}
module LetterSpacing = {
type letterSpacing = Css_AtomicTypes.Length.t
let letterSpacing = identity
}
module Typography = {
include FontSize
include FontFamily
include FontWeight
include LineHeight
include LetterSpacing
}
module BoxShadows = {
type boxShadow = AncestorCss_WrappedTypes.BoxShadow.t
let boxShadow = identity
}
module TextShadows = {
type textShadow = AncestorCss_WrappedTypes.TextShadow.t
let textShadow = identity
}
module Shadows = {
include BoxShadows
include TextShadows
}
}
module Make = (
Breakpoints: AncestorCss_Config.Breakpoints,
CustomColors: AncestorCss_Config.Colors,
CustomSpacing: AncestorCss_Config.Spacing,
CustomRadius: AncestorCss_Config.Radius,
CustomZIndex: AncestorCss_Config.ZIndex,
CustomTypography: AncestorCss_Config.Typography,
CustomShadows: AncestorCss_Config.Shadows,
) => {
include CssJs
let zIndex = x => Css_Js_Core.zIndex(x->CustomZIndex.zIndex)
/*
* Colors
*/
let color = x => Css_Js_Core.color(x->CustomColors.colors)
let backgroundColor = x => Css_Js_Core.backgroundColor(x->CustomColors.colors)
let border = (length, style, color) =>
Css_Js_Core.border(length, style, color->CustomColors.colors)
let borderBottom = (length, style, color) =>
Css_Js_Core.borderBottom(length, style, color->CustomColors.colors)
let borderTop = (length, style, color) =>
Css_Js_Core.borderTop(length, style, color->CustomColors.colors)
let borderLeft = (length, style, color) =>
Css_Js_Core.borderLeft(length, style, color->CustomColors.colors)
let borderRight = (length, style, color) =>
Css_Js_Core.borderRight(length, style, color->CustomColors.colors)
let borderColor = x => Css_Js_Core.borderColor(x->CustomColors.colors)
let borderTopColor = x => Css_Js_Core.borderTopColor(x->CustomColors.colors)
let borderBottomColor = x => Css_Js_Core.borderBottomColor(x->CustomColors.colors)
let borderLeftColor = x => Css_Js_Core.borderLeftColor(x->CustomColors.colors)
let borderRightColor = x => Css_Js_Core.borderRightColor(x->CustomColors.colors)
let textDecorationColor = x => Css_Js_Core.textDecorationColor(x->CustomColors.colors)
let outline = (size, style, color) => Css_Js_Core.outline(size, style, color->CustomColors.colors)
let outlineColor = x => Css_Js_Core.outlineColor(x->CustomColors.colors)
/*
* Radius
*/
let borderRadius = x => Css_Js_Core.borderRadius(x->CustomRadius.radius)
let borderTopLeftRadius = x => Css_Js_Core.borderTopLeftRadius(x->CustomRadius.radius)
let borderTopRightRadius = x => Css_Js_Core.borderTopRightRadius(x->CustomRadius.radius)
let borderBottomLeftRadius = x => Css_Js_Core.borderTopLeftRadius(x->CustomRadius.radius)
let borderBottomRightRadius = x => Css_Js_Core.borderTopRightRadius(x->CustomRadius.radius)
/*
* Spacing
*/
let gap = x => x->CustomSpacing.spacing->Css_Js_Core.gap
let gap2 = (~rowGap, ~columnGap) =>
Css_Js_Core.gap2(
~rowGap=rowGap->CustomSpacing.spacing,
~columnGap=columnGap->CustomSpacing.spacing,
)
let padding = x => x->CustomSpacing.spacing->Css_Js_Core.padding
let padding2 = (~v, ~h) =>
Css_Js_Core.padding2(~v=v->CustomSpacing.spacing, ~h=h->CustomSpacing.spacing)
let padding3 = (~top, ~h, ~bottom) =>
Css_Js_Core.padding3(
~top=top->CustomSpacing.spacing,
~h=h->CustomSpacing.spacing,
~bottom=bottom->CustomSpacing.spacing,
)
let padding4 = (~top, ~right, ~bottom, ~left) =>
Css_Js_Core.padding4(
~top=top->CustomSpacing.spacing,
~right=right->CustomSpacing.spacing,
~bottom=bottom->CustomSpacing.spacing,
~left=left->CustomSpacing.spacing,
)
let paddingBottom = x => x->CustomSpacing.spacing->Css_Js_Core.paddingBottom
let paddingLeft = x => x->CustomSpacing.spacing->Css_Js_Core.paddingLeft
let paddingTop = x => x->CustomSpacing.spacing->Css_Js_Core.paddingTop
let paddingRight = x => x->CustomSpacing.spacing->Css_Js_Core.paddingRight
let margin = x => x->CustomSpacing.spacing->Css_Js_Core.margin
let margin2 = (~v, ~h) =>
Css_Js_Core.margin2(~v=v->CustomSpacing.spacing, ~h=h->CustomSpacing.spacing)
let margin3 = (~top, ~h, ~bottom) =>
Css_Js_Core.margin3(
~top=top->CustomSpacing.spacing,
~h=h->CustomSpacing.spacing,
~bottom=bottom->CustomSpacing.spacing,
)
let margin4 = (~top, ~right, ~bottom, ~left) =>
Css_Js_Core.margin4(
~top=top->CustomSpacing.spacing,
~right=right->CustomSpacing.spacing,
~bottom=bottom->CustomSpacing.spacing,
~left=left->CustomSpacing.spacing,
)
let marginBottom = x => x->CustomSpacing.spacing->Css_Js_Core.marginBottom
let marginLeft = x => x->CustomSpacing.spacing->Css_Js_Core.marginLeft
let marginTop = x => x->CustomSpacing.spacing->Css_Js_Core.marginTop
let marginRight = x => x->CustomSpacing.spacing->Css_Js_Core.marginRight
let breakpoint = (token: Breakpoints.breakpoints, styles) =>
Css_Js_Core.media(.
`(min-width:${token->Breakpoints.sizeByBreakpoints->Js.Int.toString}px)`,
styles,
)
/*
* Typography
*/
let fontFamily = x => x->CustomTypography.fontFamily->Css_Js_Core.fontFamily
let fontSize = x => x->CustomTypography.fontSize->Css_Js_Core.fontSize
let fontWeight = x => x->CustomTypography.fontWeight->Css_Js_Core.fontWeight
let lineHeight = x => x->CustomTypography.lineHeight->Css_Js_Core.lineHeight
let letterSpacing = x => x->CustomTypography.letterSpacing->Css_Js_Core.letterSpacing
/*
* Shadows
*/
module TokenizedShadow = {
let box = (~x=?, ~y=?, ~blur=?, ~spread=?, ~inset=?, color) =>
CssJs.Shadow.box(~x?, ~y?, ~blur?, ~spread?, ~inset?, color)
let text = (~x=?, ~y=?, ~blur=?, color) => CssJs.Shadow.text(~x?, ~y?, ~blur?, color)
}
let boxShadow = x => x->CustomShadows.boxShadow->CssJs.boxShadow
let textShadow = x => x->CustomShadows.textShadow->CssJs.textShadow
/*
* HACK: Unfortunately we need to override these two fucntions
* because we can't convert an array of tokens into an array of box-shadows.
*/
let boxShadows = x => {
let value =
x
->Js.Array2.map(CustomShadows.boxShadow)
->Js.Array2.map(x =>
switch x {
| #...Css_Js_Core.Shadow.t as value => Css_Js_Core.Shadow.toString(value)
| #...Css_AtomicTypes.Var.t as value => Css_AtomicTypes.Var.toString(value)
}
)
->Js.Array2.joinWith(", ")
CssJs.unsafe("boxShadow", value)
}
let textShadows = x => {
let value =
x
->Js.Array2.map(CustomShadows.textShadow)
->Js.Array2.map(x =>
switch x {
| #...Css_Js_Core.Shadow.t as value => Css_Js_Core.Shadow.toString(value)
| #...Css_AtomicTypes.Var.t as value => Css_AtomicTypes.Var.toString(value)
}
)
->Js.Array2.joinWith(", ")
CssJs.unsafe("textShadow", value)
}
/*
* Aliases to make the DX compatible with @ancestor-ui/core
*/
let bgColor = backgroundColor
let minW = minWidth
let maxW = maxWidth
let minH = minHeight
let maxH = maxHeight
}
================================================
FILE: packages/css/src/AncestorCss_Config.res
================================================
module type Spacing = {
type spacing
let spacing: spacing => Css_AtomicTypes.Length.t
}
module type Radius = {
type radius
let radius: radius => Css_AtomicTypes.Length.t
}
module type ZIndex = {
type zIndex
let zIndex: zIndex => int
}
module type Colors = {
type colors
let colors: colors => AncestorCss_WrappedTypes.Color.t
}
module type Breakpoints = {
type breakpoints
let sizeByBreakpoints: breakpoints => int
}
module type Typography = {
type fontFamily
type fontSize
type fontWeight
type lineHeight
type letterSpacing
let fontFamily: fontFamily => AncestorCss_WrappedTypes.FontFamily.t
let fontSize: fontSize => Css_AtomicTypes.Length.t
let fontWeight: fontWeight => Css_AtomicTypes.FontWeight.t
let lineHeight: lineHeight => AncestorCss_WrappedTypes.LineHeight.t
let letterSpacing: letterSpacing => Css_AtomicTypes.Length.t
}
module type Shadows = {
type textShadow
type boxShadow
let textShadow: textShadow => AncestorCss_WrappedTypes.TextShadow.t
let boxShadow: boxShadow => AncestorCss_WrappedTypes.BoxShadow.t
}
================================================
FILE: packages/css/src/AncestorCss_Context.res
================================================
================================================
FILE: packages/css/src/AncestorCss_Stories.res
================================================
let default = Storybook.story(~title="Basic usage", ~excludeStories=["CustomCss"], ())
module CustomCss = AncestorCss.Make(
AncestorCss.Defaults.Breakpoints,
{
type colors = [#primary | #secondary]
let colors = (x: colors) =>
switch x {
| #primary => #hex("fc0")
| #secondary => #hex("363636")
}
},
AncestorCss.Defaults.Spacing,
AncestorCss.Defaults.Radius,
AncestorCss.Defaults.ZIndex,
AncestorCss.Defaults.Typography,
{
include AncestorCss.Defaults.TextShadows
type boxShadow = [
| #simple
| #cool
]
let boxShadow = x =>
switch x {
| #simple => CssJs.Shadow.box(~x=1->#px, ~y=2->#px, #hex("363636"))
| #cool => #var("--cool-shadow")
}
},
)
let overview = () => {
open CustomCss
let className = style(. [
width(124->#px),
height(124->#px),
boxShadow(#cool),
bgColor(#secondary),
fontSize(24->#px),
breakpoint(
#sm,
[
boxShadow(#simple),
bgColor(#primary),
padding(4),
borderRadius(2),
border(1->#px, #solid, #primary),
width(300->#px),
height(300->#px),
],
),
])
}
================================================
FILE: packages/css/src/AncestorCss_WrappedTypes.res
================================================
module LineHeight = {
type t = [
| #ch(float)
| #em(float)
| #ex(float)
| #rem(float)
| #vh(float)
| #vw(float)
| #vmin(float)
| #vmax(float)
| #px(int)
| #pxFloat(float)
| #cm(float)
| #mm(float)
| #inch(float)
| #pc(float)
| #pt(int)
| #zero
| #calc([#add | #sub | #mult], Css_AtomicTypes.Length.t, Css_AtomicTypes.Length.t)
| #percent(float)
| #var(string)
| #varDefault(string, string)
| #normal
| #abs(float)
| #initial
| #inherit_
| #unset
]
let toRule: t => CssJs.rule = CssJs.lineHeight
}
module FontFamily = {
type t = [
| #custom(string)
| #serif
| #sansSerif
| #cursive
| #fantasy
| #monospace
| #systemUi
| #emoji
| #math
| #fangsong
| #var(string)
| #varDefault(string, string)
| #initial
| #inherit_
| #unset
]
let toRule: t => CssJs.rule = CssJs.fontFamily
}
module Color = {
open Css_AtomicTypes
type t = [
| #rgb(int, int, int)
| #rgba(int, int, int, [#num(float) | Percentage.t])
| #hsl(Angle.t, Percentage.t, Percentage.t)
| #hsla(Angle.t, Percentage.t, Percentage.t, [#num(float) | Percentage.t])
| #hex(string)
| #transparent
| #currentColor
| #var(string)
| #varDefault(string, string)
]
let toRule: t => CssJs.rule = CssJs.color
}
module BoxShadow = {
type t = [
| #none
| #shadow(CssJs.Shadow.value)
| #var(string)
| #varDefault(string, string)
]
let toRule: t => CssJs.rule = CssJs.boxShadow
}
module TextShadow = {
type t = [
| #none
| #shadow(CssJs.Shadow.value)
| #var(string)
| #varDefault(string, string)
]
let toRule: t => CssJs.rule = CssJs.textShadow
}
================================================
FILE: packages/ui/.storybook/main.js
================================================
module.exports = {
stories: ["../src/**/*_Stories.bs.js"],
addons: [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions",
],
framework: "@storybook/react",
};
================================================
FILE: packages/ui/.storybook/preview-head.html
================================================
================================================
FILE: packages/ui/.storybook/preview.js
================================================
export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
}
================================================
FILE: packages/ui/bsconfig.json
================================================
{
"name": "@rescriptbr/ancestor-ui",
"namespace": "AncestorUI",
"version": "0.0.1",
"sources": [
{
"dir": "src",
"subdirs": true
}
],
"package-specs": [
{
"module": "commonjs",
"in-source": true
}
],
"jsx": { "version": 4, "mode": "classic" },
"suffix": ".bs.js",
"bs-dependencies": [
"@rescript/react",
"@ancestor-ui/core",
"@ancestor-ui/bindings",
"@ancestor-ui/css",
"bs-css",
"bs-css-emotion"
],
"bs-dev-dependencies": [],
"ppx-flags": []
}
================================================
FILE: packages/ui/package.json
================================================
{
"name": "@rescriptbr/ancestor-ui",
"version": "0.0.1",
"main": "index.js",
"license": "MIT",
"devDependencies": {
"@babel/core": "7.20.5",
"@emotion/css": "11.10.0",
"@emotion/jest": "11.9.3",
"@rescript/react": "0.11.0-rc.3",
"@storybook/addon-actions": "6.5.15",
"@storybook/addon-essentials": "6.5.15",
"@storybook/addon-interactions": "6.5.15",
"@storybook/addon-links": "6.5.15",
"@storybook/builder-webpack4": "6.5.15",
"@storybook/manager-webpack4": "6.5.15",
"@storybook/react": "6.5.15",
"@storybook/testing-library": "0.0.13",
"babel-loader": "8.3.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"rescript": "10.1.0"
},
"peerDependencies": {
"@rescript/react": ">=0.11",
"react": ">=18",
"react-dom": ">=18",
"rescript": ">=10"
},
"dependencies": {
"@ancestor-ui/core": "0.5.0",
"@ancestor-ui/bindings": "0.1.0"
},
"scripts": {
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook"
}
}
================================================
FILE: packages/ui/src/AncestorUI.res
================================================
module Make = (
// Config
BreakpointsConfig: Ancestor_Config.Breakpoints,
ColorsConfig: Theme.CustomColorsConfig,
SpacingConfig: AncestorCss_Config.Spacing,
RadiusConfig: AncestorCss_Config.Radius,
ZIndexConfig: AncestorCss_Config.ZIndex,
Theme: Theme.T,
) => {
module Config = {
include BreakpointsConfig
include ColorsConfig
include SpacingConfig
include RadiusConfig
include ZIndexConfig
include Theme
}
module Button = Button.Make(Config)
}
================================================
FILE: packages/ui/src/Theme.res
================================================
module Colors = {
type colors<'custom> = [#primary | #secondary | #custom('custom)]
}
module type CustomColorsConfig = {
type colors
let colors: Colors.colors => Css_AtomicTypes.Color.t
}
type theme = {button?: ButtonTokens.api}
module type T = {
let theme: theme
}
module type Config = {
type breakpoints<'value>
type keyOfBreakpoints
type spacing
type radius
type colors
type zIndex
let encode: breakpoints<'value> => array<(keyOfBreakpoints, option<'value>)>
let zIndex: zIndex => int
let colors: Colors.colors => Css_AtomicTypes.Color.t
let spacing: spacing => Css_AtomicTypes.Length.t
let radius: radius => Css_AtomicTypes.Length.t
let sizeByBreakpoints: keyOfBreakpoints => int
let theme: theme
}
================================================
FILE: packages/ui/src/components/button/Button.res
================================================
module Make = (Theme: Theme.Config) => {
@react.component
let make = () =>
}
================================================
FILE: packages/ui/src/components/button/ButtonTokens.res
================================================
type size = [#xs | #sm | #md | #lg]
type color = [#primary | #secondary]
type defaults = {
size?: size,
colors?: color,
}
type api = {
baseStyles?: array,
size?: size => array,
color?: color => array,
defaults?: defaults,
}
================================================
FILE: packages/ui/src/lib/AncestorCore.res
================================================
module Make = (Config: Theme.Config) => {
include Ancestor.Make(
{
type breakpoints<'value> = Config.breakpoints<'value>
type keyOfBreakpoints = Config.keyOfBreakpoints
let encode = Config.encode
let sizeByBreakpoints = Config.sizeByBreakpoints
},
{
type colors = Theme.Colors.colors
let colors = Config.colors
},
{
type spacing = Config.spacing
let spacing = Config.spacing
},
{
type radius = Config.radius
let radius = Config.radius
},
{
type zIndex = Config.zIndex
let zIndex = Config.zIndex
},
)
}
================================================
FILE: website/.gitignore
================================================
# Dependencies
/node_modules
# Production
/build
# Generated files
.docusaurus
.cache-loader
# Misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
================================================
FILE: website/.prettierignore
================================================
*.bs.js
================================================
FILE: website/.prettierrc
================================================
{
"singleQuote": true,
"jsxSingleQuote": true,
"semi": false,
"trailingComma": "all"
}
================================================
FILE: website/README.md
================================================
# Website
This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.
## Installation
```console
yarn install
```
## Local Development
```console
yarn start
```
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
## Build
```console
yarn build
```
This command generates static content into the `build` directory and can be served using any static contents hosting service.
## Deployment
```console
GIT_USER= USE_SSH=true yarn deploy
```
If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.
================================================
FILE: website/babel.config.js
================================================
module.exports = {
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
}
================================================
FILE: website/bsconfig.json
================================================
{
"name": "website",
"version": "0.0.1",
"sources": [
{
"dir": "src",
"subdirs": true
},
{
"dir": "docs",
"subdirs": true
}
],
"package-specs": [
{
"module": "es6",
"in-source": true
}
],
"reason": {
"react-jsx": 3
},
"suffix": ".bs.js",
"bs-dependencies": ["@rescript/react", "@rescriptbr/ancestor"]
}
================================================
FILE: website/docs/_components/Placeholder.res
================================================
open Ancestor
@react.component
let make = (
~children=React.null,
~bgColor=[xs(Theme.Colors.black)],
~width=[xs(7.2->#rem)],
~height=[xs(7.2->#rem)],
) =>
#rem)]
textAlign=[xs(#center)]
display=[xs(#flex)]
alignItems=[xs(#center)]
justifyContent=[xs(#center)]
fontSize=[xs(18->#px)]
fontWeight=[xs(#700)]
width
height
color=[xs(Theme.Colors.white)]
borderRadius=[xs(1)]
bgColor>
children
================================================
FILE: website/docs/_helpers/Emotion.res
================================================
@module("@emotion/css") external css: {..} => string = "css"
================================================
FILE: website/docs/_helpers/Helpers.res
================================================
open Ancestor
let \"Wrapper" = props => {
#px, #solid, #hex("#cecece"))->xs]
p=[xs(2), md(4)]
bgColor=[xs(#hex("#fff"))]
borderRadius=[xs(1)]>
{props["children"]}
}
================================================
FILE: website/docs/_helpers/Theme.res
================================================
module Colors = {
let black = #hex("#000")
let white = #hex("#fafafa")
let pink = #hex("#f36")
let gray1 = #hex("#545454")
let gray2 = #hex("#a1a1a1")
}
================================================
FILE: website/docs/_helpers/index.js
================================================
export * from './Helpers.bs'
================================================
FILE: website/docs/api/base.md
================================================
---
title:
---
import CodeBlock from '@theme/CodeBlock'
import { Wrapper, cleanUpCode } from '../_helpers'
import { make as FirstBaseExample } from './examples/FirstBaseExample.bs'
import FirstBaseExampleSource from '!!raw-loader!./examples/FirstBaseExample.res'
` ` works as a component to build other components that accepts responsive props.
## Example
{FirstBaseExampleSource}
## Props
Base component accepts all props defined by the [system props](/docs/system-props).
Furthermore, the component accepts the following properties:
### `tag`
Defines the tag that will be rendered
Default: `#div`
- Type: `responsiveProp<[`
- `| #a`
- `| #abbr`
- `| #acronym`
- `| #address`
- `| #applet`
- `| #area`
- `| #article`
- `| #aside`
- `| #audio`
- `| #b`
- `| #base`
- `| #basefont`
- `| #bdo`
- `| #big`
- `| #blockquote`
- `| #body`
- `| #br`
- `| #button`
- `| #canvas`
- `| #caption`
- `| #center`
- `| #cite`
- `| #code`
- `| #col`
- `| #colgroup`
- `| #datalist`
- `| #dd`
- `| #del`
- `| #dfn`
- `| #div`
- `| #dl`
- `| #dt`
- `| #em`
- `| #embed`
- `| #fieldset`
- `| #figcaption`
- `| #figure`
- `| #font`
- `| #footer`
- `| #form`
- `| #frame`
- `| #frameset`
- `| #head`
- `| #header`
- `| #h1`
- `| #h2`
- `| #h3`
- `| #h3`
- `| #h4`
- `| #h5`
- `| #h6`
- `| #hr`
- `| #html`
- `| #i`
- `| #iframe`
- `| #img`
- `| #input`
- `| #ins`
- `| #kbd`
- `| #label`
- `| #legend`
- `| #li`
- `| #link`
- `| #main`
- `| #map`
- `| #mark`
- `| #meta`
- `| #meter`
- `| #nav`
- `| #noscript`
- `| #object`
- `| #ol`
- `| #optgroup`
- `| #option`
- `| #p`
- `| #param`
- `| #pre`
- `| #progress`
- `| #q`
- `| #s`
- `| #samp`
- `| #script`
- `| #section`
- `| #select`
- `| #small`
- `| #source`
- `| #span`
- `| #strike`
- `| #strong`
- `| #style`
- `| #sub`
- `| #sup`
- `| #table`
- `| #tbody`
- `| #td`
- `| #textarea`
- `| #tfoot`
- `| #th`
- `| #thead`
- `| #time`
- `| #title`
- `| #tr`
- `| #u`
- `| #ul`
- `| #var`
- `| #video`
- `| #wbr`
`]>`
================================================
FILE: website/docs/api/box.mdx
================================================
---
title:
---
import CodeBlock from '@theme/CodeBlock'
import { Wrapper } from '../_helpers'
import { make as FirstBoxExample } from './examples/FirstBoxExample.bs'
import FirstBoxExampleSource from '!!raw-loader!./examples/FirstBoxExample.res'
` ` works as a wrapper to change the appearance of elements through utility properties.
It's also used as a column component with [` `](/docs/api/grid).
## Example
{FirstBoxExampleSource}
:::important
Resize your browser to see the responsive styles in action.
:::
## Props
` ` acceppts all props defined by the [system props](/docs/system-props).
Furthermore, it also accepts the following properties:
### `columns`
Defines the column size inside of a [Grid](/docs/api/grid) component.
- Type: `responsiveProp<[`
- ` | # auto`
- ` | #1`
- ` | #2`
- ` | #3`
- ` | #4`
- ` | #5`
- ` | #6`
- ` | #7`
- ` | #8`
- ` | #9`
- ` | #10`
- ` | #11`
- ` | #12`
`]>`
- Optional: `true`
:::important
The `responsiveProp` is a customizable type defined in the Ancestor's setup.
You can see the default breakpoints defined in the **[Ancestor's default setup](/docs/customization#default-breakpoints)** or define **[your own breakpoints](/docs/customization#custom-breakpoints)**.
:::
================================================
FILE: website/docs/api/examples/FirstBaseExample.res
================================================
open Ancestor
@react.component
let make = () => {
#pct)]>
#px)]
borderRadius=[#xs(1)]
p=[#xs(3)]
bgColor=[#xs(#hex("#000"))]
tag=#section>
#px, #solid, #hex("#f36")))]
borderRadius=[#xs(6)]
height=[#xs(96->#px)]
width=[#xs(96->#px)]
src="/img/ww-picture.png"
tag=#img
mb=[#xs(2)]
/>
#px)]
tag=#h1>
{"Walter White"->React.string}
#px)] tag=#p>
{"Teacher"->React.string}
#px)] tag=#p>
{"Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old"->React.string}
}
================================================
FILE: website/docs/api/examples/FirstBoxExample.res
================================================
open Ancestor
@react.component
let make = () => {
#px), md(32->#px)]
m=[xs(0)]>
{`Start using right now`->React.string}
#px)]>
{`Ancestor is production-ready and actively maintained. It’s used in production projects daily and keep breaking changes to a minimum whereever possible.`->React.string}
#px)]
width=[xs(256->#px)]
height=[xs(48->#px)]
borderRadius=[xs(3)]
fontWeight=[xs(#600)]
tag=#button>
{"Let's start"->React.string}
}
================================================
FILE: website/docs/api/examples/FirstGridExample.res
================================================
open Ancestor
@react.component
let make = () => {
#pct)]> {"6"->React.string}
#pct)]> {"6"->React.string}
#pct)]> {"12"->React.string}
#pct)]> {"xs 12 / md 4"->React.string}
#pct)]> {"xs 12 / md 4"->React.string}
#pct)]> {"xs 12 / md 4"->React.string}
}
================================================
FILE: website/docs/api/examples/FirstHiddenExample.res
================================================
open Ancestor
@react.component
let make = () => {
{"Visible below md"->React.string}
{"Always visible"->React.string}
{"Hidden below md"->React.string}
}
================================================
FILE: website/docs/api/examples/FirstStackExample.res
================================================
open Ancestor
@react.component
let make = () => {
#px)] width=[xs(100.0->#pct)]>
#pct)]> {"Item"->React.string}
#pct)]> {"Item"->React.string}
#pct)]> {"Item"->React.string}
}
================================================
FILE: website/docs/api/examples/SecondStackExample.res
================================================
open Ancestor
module Divider = {
@react.component
let make = () => #px)] bgColor=[xs(#hex("#cecece"))] />
}
@react.component
let make = () => {
#px)] width=[xs(100.0->#pct)]>
}>
#pct)]> {"Item"->React.string}
#pct)]> {"Item"->React.string}
#pct)]> {"Item"->React.string}
}
================================================
FILE: website/docs/api/grid.mdx
================================================
---
title:
---
import CodeBlock from '@theme/CodeBlock'
import { Wrapper, cleanUpCode } from '../_helpers'
import { make as FirstGridExample } from './examples/FirstGridExample.bs.js'
import FirstGridExampleSource from '!!raw-loader!./examples/FirstGridExample.res'
` ` is a component based on a 12-column grid layout.
## Example
{FirstGridExampleSource}
:::important
Resize your browser to see the responsive styles in action.
:::
## Props
` ` accepts all props defined by the [system props](/docs/system-props).
Furthermore, it also accepts the following properties:
### `spacing`
- Type: `responsiveProp`
- Optional: `true`
:::important
The `responsiveProp` is a customizable type defined in the Ancestor's setup.
You can see the default breakpoints defined in the **[Ancestor's default setup](/docs/customization#default-breakpoints)** or define **[your own breakpoints](/docs/customization#custom-breakpoints)**.
:::
================================================
FILE: website/docs/api/hidden.md
================================================
---
title:
---
import CodeBlock from '@theme/CodeBlock'
import { Wrapper } from '../_helpers'
import { make as FirstHiddenExample } from './examples/FirstHiddenExample.bs'
import FirstHiddenExampleSource from '!!raw-loader!./examples/FirstHiddenExample.res'
` ` is used to visually hide components.
## Example
{FirstHiddenExampleSource}
:::important
Resize your browser to see the responsive styles in action.
:::
## Props
` ` acceppts all props defined by the [system props](/docs/system-props).
Furthermore, it also accepts the following properties:
### `on`
- Type: `responsiveProp`
- Optional: True
:::important
The `responsiveProp` is a customizable type defined in the Ancestor's setup.
You can see the default breakpoints defined in the **[Ancestor's default setup](/docs/customization#default-breakpoints)** or define **[your own breakpoints](/docs/customization#custom-breakpoints)**.
:::
================================================
FILE: website/docs/api/stack.md
================================================
---
title:
---
import CodeBlock from '@theme/CodeBlock'
import { Wrapper } from '../_helpers'
import { make as FirstStackExample } from './examples/FirstStackExample.bs'
import { make as SecondStackExample } from './examples/SecondStackExample.bs'
import FirstStackExampleSource from '!!raw-loader!./examples/FirstStackExample.res'
import SecondStackExampleSource from '!!raw-loader!./examples/SecondStackExample.res'
` ` is a component used to group elements together.
## Example
{FirstStackExampleSource}
:::important
Resize your browser to see the responsive styles in action.
:::
## Using dividers
{SecondStackExampleSource}
## Props
` ` accepts all props defined by the system props. Furthermore, it also accepts the following properties:
### `spacing`
- Type: `responsiveProp`
- Optional: True
### `direction`
- Type: `responsiveProp<[ #vertical | #horizontal ]>`
- Optional: True
### `divider`
- Type: `React.element`
- Optional: True
:::important
The `responsiveProp` is a customizable type defined in the Ancestor's setup.
You can see the default breakpoints defined in the **[Ancestor's default setup](/docs/customization#default-breakpoints)** or define **[your own breakpoints](/docs/customization#custom-breakpoints)**.
:::
================================================
FILE: website/docs/customization/Customization_Breakpoints1.res
================================================
module AncestorCustom = Ancestor.Make({
open Ancestor.DefaultConfig
// highlight-start
type breakpoints<'value> = [
| #small('value)
| #medium('value)
| #large('value)
]
let sizeByBreakpoints = values =>
switch values {
| #small(_) => 0
| #medium(_) => 600
| #large(_) => 1280
}
let unboxBreakpointValue = values =>
switch values {
| #small(v) => v
| #medium(v) => v
| #large(v) => v
}
// highlight-end
type spacing = spacing
let spacing = spacing
type radius = radius
let radius = radius
type colors = colors
let colors = colors
type zIndex = zIndex
let zIndex = zIndex
let css = Ancestor.DefaultConfig.css
})
module App = {
open AncestorCustom
@react.component
let make = () => {
{"Your components here..."->React.string}
}
}
================================================
FILE: website/docs/customization/Customization_Colors1.res
================================================
module AncestorCustom = Ancestor.Make({
open Ancestor.DefaultConfig
type breakpoints<'value> = breakpoints<'value>
let unboxBreakpointValue = unboxBreakpointValue
let sizeByBreakpoints = sizeByBreakpoints
let css = css
type spacing = spacing
let spacing = spacing
type zIndex = zIndex
let zIndex = zIndex
//highlight-start
type colors = [
| #primary100
| #secondary100
| #background
]
let colors = token =>
switch token {
| #primary100 => #hex("#000")
| #secondary100 => #hex("#cecece")
| #background => #hex("#fafafa")
}
//highlight-end
type radius = radius
let radius = radius
})
@react.component
let make = () => {
open AncestorCustom
// highlight-start
{"Your text here..."->React.string}
// highlight-end
}
================================================
FILE: website/docs/customization/Customization_Radius1.res
================================================
module AncestorCustom = Ancestor.Make({
open Ancestor.DefaultConfig
type breakpoints<'value> = breakpoints<'value>
let unboxBreakpointValue = Ancestor.DefaultConfig.unboxBreakpointValue
let sizeByBreakpoints = Ancestor.DefaultConfig.sizeByBreakpoints
let css = Ancestor.DefaultConfig.css
type spacing = spacing
let spacing = spacing
type zIndex = zIndex
let zIndex = zIndex
type colors = colors
let colors = colors
// highlight-start
type radius = Ancestor_Css.Length.t
let radius = v => v
// highlight-end
})
@react.component
let make = () => {
open AncestorCustom
// highlight-start
#px)]> #px)] />
// highlight-end
}
================================================
FILE: website/docs/customization/Customization_Spacing1.res
================================================
module AncestorCustom = Ancestor.Make({
include Ancestor.DefaultConfig
let spacing = v => #px(v * 4)
})
================================================
FILE: website/docs/customization/Customization_Spacing2.res
================================================
module AncestorCustom = Ancestor.Make({
open Ancestor.DefaultConfig
type breakpoints<'value> = breakpoints<'value>
let sizeByBreakpoints = sizeByBreakpoints
let unboxBreakpointValue = unboxBreakpointValue
//highlight-start
type spacing = float
let spacing = v => #pxFloat(v *. 8.0)
//highlight-end
type radius = radius
let radius = radius
type colors = colors
let colors = colors
type zIndex = zIndex
let zIndex = zIndex
let css = Ancestor.DefaultConfig.css
})
@react.component
let make = () => {
open AncestorCustom
//highlight-start
//highlight-end
}
================================================
FILE: website/docs/customization/Customization_Spacing3.res
================================================
module AncestorCustom = Ancestor.Make({
open Ancestor.DefaultConfig
type breakpoints<'value> = breakpoints<'value>
let sizeByBreakpoints = sizeByBreakpoints
let unboxBreakpointValue = unboxBreakpointValue
//highlight-start
type spacing = [#xs | #md | #lg]
let spacing = v =>
switch v {
| #xs => #px(8)
| #md => #px(16)
| #lg => #px(24)
}
//highlight-end
type radius = radius
let radius = radius
type colors = colors
let colors = colors
type zIndex = zIndex
let zIndex = zIndex
let css = Ancestor.DefaultConfig.css
})
@react.component
let make = () => {
open AncestorCustom
}
================================================
FILE: website/docs/customization/Customization_Spacing4.res
================================================
module AncestorCustom = Ancestor.Make({
open Ancestor.DefaultConfig
type breakpoints<'value> = breakpoints<'value>
let unboxBreakpointValue = Ancestor.DefaultConfig.unboxBreakpointValue
let sizeByBreakpoints = Ancestor.DefaultConfig.sizeByBreakpoints
let css = Ancestor.DefaultConfig.css
type zIndex = zIndex
let zIndex = zIndex
type colors = colors
let colors = colors
type radius = radius
let radius = radius
// highlight-start
type spacing = Ancestor_Css.Length.t
let spacing = v => v
// highlight-end
})
@react.component
let make = () => {
open AncestorCustom
// highlight-start
#px)]> #px)] />
// highlight-end
}
================================================
FILE: website/docs/customization/Customization_ZIndex1.res
================================================
module AncestorCustom = Ancestor.Make({
open Ancestor.DefaultConfig
type breakpoints<'value> = breakpoints<'value>
let unboxBreakpointValue = unboxBreakpointValue
let sizeByBreakpoints = sizeByBreakpoints
let css = css
type spacing = spacing
let spacing = spacing
//highlight-start
type zIndex = [
| #base
| #above
| #aboveAll
]
let zIndex = token =>
switch token {
| #base => 5
| #above => 15
| #aboveAll => 20
}
//highlight-end
type colors = colors
let colors = colors
type radius = radius
let radius = radius
})
@react.component
let make = () => {
open AncestorCustom
// highlight-start
// highlight-end
}
================================================
FILE: website/docs/customization/customization.md
================================================
import CodeBlock from '@theme/CodeBlock'
import { Wrapper, cleanUpCode } from '../_helpers'
import CustomizatBreakpoints1 from '!!raw-loader!./Customization_Breakpoints1.res'
import CustomizationSpacing1 from '!!raw-loader!./Customization_Spacing1.res'
import CustomizationSpacing2 from '!!raw-loader!./Customization_Spacing2.res'
import CustomizationSpacing3 from '!!raw-loader!./Customization_Spacing3.res'
import CustomizationSpacing4 from '!!raw-loader!./Customization_Spacing4.res'
import CustomizationRadius1 from '!!raw-loader!./Customization_Radius1.res'
import CustomizationColors1 from '!!raw-loader!./Customization_Colors1.res'
import CustomizationZIndex1 from '!!raw-loader!./Customization_ZIndex1.res'
# Customization
Ancestor take advantage of [Module Functors](https://rescript-lang.org/docs/manual/v8.0.0/module#module-functions-functors) for customization of breakpoints, spacing, radius, etc.
## Default setup
The customization interface has the following type signature:
```rescript title="Ancestor_Config.res"
module type T = {
type breakpoints<'value>
type spacing
type radius
type colors
type zIndex
let spacing: spacing => Ancestor_Css.Length.t
let radius: radius => Ancestor_Css.Length.t
let unboxBreakpointValue: breakpoints<'value> => 'value
let sizeByBreakpoints: breakpoints<'value> => int
let css: string => string
}
```
And the default setup has the following values and types:
```rescript
module DefaultConfig = {
type breakpoints<'a> = [#xs('a) | #sm('a) | #md('a) | #lg('a) | #xl('a)]
let sizeByBreakpoints = values =>
switch values {
| #xs(_) => 0
| #sm(_) => 475
| #md(_) => 920
| #lg(_) => 1280
| #xl(_) => 1920
}
let unboxBreakpointValue = values =>
switch values {
| #xs(v) => v
| #sm(v) => v
| #md(v) => v
| #lg(v) => v
| #xl(v) => v
}
type colors = Ancestor_Css.Color.t
let colors = v => v
type spacing = int
let spacing = spacing => #px(spacing * 8)
type radius = int
let radius = radius => #px(radius * 8)
type zIndex = int
let zIndex = v => v
let css = Ancestor_Emotion.css
}
```
## Breakpoints
### Default breakpoints
Ancestor's breakpoints are customizable. The default setup has the following values:
- `xs` 0px → 475px
- `sm` 475px → 920px
- `md` 920px → 1280px
- `lg` 1280px → 1440px
- `xl` 1440px
### Custom breakpoints
If you wish, you can customize **only** the breakpoints by overriding all types and values from the default setup:
{CustomizatBreakpoints1}
Beyond the type definition, you need to define two functions:
#### `sizeByBreakpoints`
- Type: `let sizeByBreakpoints: breakpoints<'value> => int`
- Description: A function that receives a `breakpoint<'value>` and returns an integer (the breakpoint value in `px`).
#### `unboxBreakpointValue`
- Type: `let unboxBreakpointValue: breakpoints<'value> => 'value`
- Description: A function that receives a `breakpoint<'value>`, "unbox" and returns its value.
:::important
All Ancestor's components properties are an **array** of **breakpoints**. If you want a property with the same value in all breakpoints, you need to provide the value for the lowest breakpoint.
:::
:::tip
If you wish, you can create **"aliases functions"** to replace the variants that you defined in your custom setup.
Instead of write `display=[#xs(#flex)]` you can write `display=[xs(#flex)]`. In some cases, it improves the code readability.
:::
## Spacing
The `spacing` api is fully customizable. By default, Ancestor uses `int` and a scale factor of `8px` to keep the spacing consistent between the elements.
You can customize the scale factor by providing a new value for the `spacing` function:
{CustomizationSpacing1}
### Customizing the type of `spacing` props
You can also customize the type of the spacing properties. This feature is very useful when you need to use scale values like `1.25`, `2.5`, etc. Let's see how to use `float` instead of int:
{CustomizationSpacing2}
### Using design tokens
We can also define a set of spacing tokens using polymorphic variants. Sometimes the design team doesn't use scale values like `1` or `1.5`, but they define a set of design tokens that represents a value in `px`. Let's see how to do this with Ancestor:
{CustomizationSpacing3}
### Using CSS units
Sometimes, you just want to use CSS units like `rem` or `px`:
{CustomizationSpacing4}
## Border Radius
All of those customizations above, also works for the radius. You need just to replace the `spacing` type and value by `radius`. Let's see:
{CustomizationRadius1}
## Colors
By default, Ancestor uses `Ancestor_Css.Color.t` as the type definition for the colors, which means that you're able to use
css colors like `#hex(...)` or `rgb(...)`. However, sometimes you have a well defined set of colors that you're going to use in your components.
Let's see how to combine Ancestor and polyvariants to create type safe custom design tokens:
{CustomizationColors1}
## ZIndex
By default, Ancestor uses `int` as the type definition for the `z-index`.
Managing `z-index` might become difficult sometimes. Here's an example of how combine Ancestor and polyvariants to create type safe tokens for zIndex:
{CustomizationZIndex1}
## CSS in JS
To generate styles Ancestor uses [@emotion/css](https://emotion.sh/docs/introduction).
If you wish, you can use another CSS in JS library that provides an equivalent function, like [Goober](https://github.com/cristianbote/goober#csstaggedtemplate)
or [styled-components](https://styled-components.com/docs/api#css).
```rescript
module Goober = {
@module("goober") external css: string => string = "css"
}
module AncestorCustom = Ancestor.Make({
include Ancestor.DefaultConfig
let css = Goober.css
})
```
================================================
FILE: website/docs/getting-started.md
================================================
# Getting started
Step by step to install Ancestor in your project.
:::important
This project assumes that you have a functional project with ReScript and React. Check out [how to create a ReScript project with React](https://rescript-lang.org/docs/react/latest/installation).
:::
## Installation
First off, install **Ancestor** using npm/yarn:
```sh title="Terminal"
yarn add @rescriptbr/ancestor
```
If you want to use the default setup, you need to install [Emotion](https://emotion.sh).
```sh title="Terminal"
yarn add @emotion/css
```
:::important
This step is optional. Ancestor is agnostic of CSS in JS library. You can use any CSS in JS library of your preference by providing a CSS function on the setup.
Read more about it on the [**customization section**](/docs/customization#css-in-js).
:::
Add the package to `bs-dependencies` in your `bsconfig.json`:
```json title="bsconfig.json"
{
...
"bs-dependencies": [
"@rescript/react",
"@rescriptbr/ancestor"
]
}
```
## Basic usage
Ancestor comes with a default setup. You can use the default setup by exposing the module writing `open Ancestor`:
```rescript title="App.res"
open Ancestor
@react.component
let make = () => {
{React.string("Hello")}
{React.string("World")}
}
```
:::important
If you wish, you can customize the default setup by following the **[instructions of customization](/docs/customization)**.
:::
================================================
FILE: website/docs/intro.md
================================================
# Introduction
**Ancestor** is a suite of components that works as layout primitives to develop high-quality
web apps, design systems, and style guides focused on responsiveness.
## What and Why?
Every front-end project that is using libraries based on components like [React](https://reactjs.org), faces the same situation:
**Choose or develop a UI library to develop the interfaces.**
In some cases, you can use libraries like [Chakra UI](https://chakra-ui.com/), [Material UI](https://material-ui.com/pt/), or
[Ant Design](https://material-ui.com/pt/) that delivers a set of styled components (grids, buttons, inputs, selects, etc)
and a lot of other utility functions and components for your web app.
However, in some cases, the team needs to create its own design system or style guide with a design language, colors, fonts, buttons, inputs
and other specifications created by a design team. In this case, the usage of a library like Material UI or Chakra UI might
not be the best choice, because depends on a lot of customizations or changes to adapt the library to the design specification.
It was the rescript that we created Ancestor: **to act as a foundation for your project or design system.**
## Features
### Unstyled 💀
Different from popular libraries like Material UI, we don't deliver styled components with colors, fonts, borders, etc.
All Ancestor's components are **layout primitives** with support to a lot of CSS properties like padding, margin, height, width, etc.
### Responsiveness 💡
All properties from Ancestor's components are responsive, which makes it easy to develop interfaces that need to support multiple devices.
Through the **breakpoints** defined by the library, you can change the appearance of a component in a specific device or screen size.
### Consistent design 🎨
We don't deliver styled components, but we care about design consistency, especially when dealing with spacing, borders, etc.
### Customizable ⚙️
All properties from Ancestor's components and parameters are customizable:
Breakpoints, spacing, radius, grid columns, etc which makes it easy to customize and adapt Ancestor to your design system or style guide.
## Basic usage
```rescript
open Ancestor
@react.component
let make = () => {
#pct)]>
#rem), md(20.0->#rem)]
>
{"A place to share knowledge"->React.string}
{"Where good ideas find you."->React.string}
#rem)]
left=[xs(-5.0->#rem)]
>
....
}
```
_ Example from [ReScript Conduit](https://github.com/rescriptbr/rescript-conduit/blob/master/src/pages/Signin/Signin.res)_
================================================
FILE: website/docs/system-props.md
================================================
---
title: System props
---
# System props
This page list all utility props of all Ancestor's components like `Base` or `Box`.
## API
:::caution
We don't support all CSS props yet. It's still work in progress.
:::
Since all Ancestor's utility props are responsive, they are typed as `responsiveProp<'value>`.
If you want to understand more, see the following example:
```rescript title=Ancestor_Styles.res
type responsiveProp = array>
```
> :bulb: Check out the module [Ancestor_Styles.res](https://github.com/rescriptbr/ancestor/blob/master/lib/src/core/Ancestor_Styles.res#L15).
The breakpoint type is customizable (check out the [customization section](/docs/customization)), by default it has the following type signature:
```rescript
type breakpoint<'a> = [#xs('value') | #md('a) | #lg('a) | #xl('a)]
```
Now, see a type signature of a component property:
```rescript title=Ancestor_Base.res
module Base = {
@react.component
let make = (
~display: option>=?,
// Other props
) => // ...
}
```
_Check out the module [Ancestor_Base.res](https://github.com/rescriptbr/ancestor/blob/master/lib/src/core/Ancestor_Base.res)_.
Example of usage:
```rescript title=App.res
open Ancestor.Default
...
```
:::important
All utility props are optional.
:::
### Properties reference
### Spacing
:::important
Check out the [`Config.spacing`](/docs/system-props#configspacing) type signature.
:::
#### `p`
- CSS Key: `padding`
- Type: `responsiveProp`
#### `px`
- CSS Key: `padding-left`, `padding-right`
- Type: `responsiveProp`
#### `py`
- CSS Key: `padding-top`, `padding-bottom`
- Type: `responsiveProp`
#### `m`
- CSS Key: `margin`
- Type: `responsiveProp`
#### `mx`
- CSS Key: `margin-left`, `margin-right`
- Type: `responsiveProp`
#### `my`
- CSS Key: `margin-top`, `margin-bottom`
- Type: `responsiveProp`
### Flex
#### `justifyContent`
- CSS Key: `justify-content`
- Type: `responsiveProp<[`
- `| #initial `
- `| #"space-between" `
- `| #center `
- `| #"flex-start" `
- `| #"flex-end" `
- `| #"space-around" `
- `| #"space-evenly" `
- `| #start `
- `| #end `
- `| #left `
- `| #right `
- `| #revert `
- `| #unset `
`]>`
#### `alignItems`
- CSS Key: `align-items`
- Type: `responsiveProp< [|`
- `| #initial `
- `| #center `
- `| #start `
- `| #end `
- `| #"flex-start" `
- `| #"flex-end" `
- `| #"self-start" `
- `| #"self-end" `
`]>`
#### `flexDirection`
- CSS Key: `flex-direction`
- Type: `responsiveProp<[`
- `| #row `
- `| #"row-reverse" `
- `| #column `
- `| #"column-reverse" `
- `| #inherit `
- `| #initial `
- `| #unset `
`]>`
#### `flexBasis`
- CSS Key: `flex-basis`
- Type: `responsiveProp<[`
- `| #length(Length.t) `
- `| #auto `
- `| #fill `
- `| #content `
- `| #"max-content" `
- `| #"min-content" `
- `| #"fit-content" `
`]>`
#### `flexWrap`
- CSS Key: `flex-wrap`
- Type: `responsiveProp<[`
- `| #nowrap `
- `| #wrap `
- `| #"wrap-reverse" `
- `| #inherit `
- `| #initial `
- `| #unset`
`]>`
#### `flexGrow`
- CSS Key: `flex-grow`
- Type: `responsiveProp<[`
- `| #num(float) `
- `| #inherit `
- `| #initial`
- `| #revert `
- `| #unset `
`]>`
#### `alignContent`
- CSS Key: `align-content`
- Type: `responsiveProp<[`
- `| #center `
- `| #start `
- `| #end `
- `| #"flex-end" `
- `| #normal `
- `| #baseline `
- `| #"first-baseline" `
- `| #"last-baseline" `
- `| #"space-between" `
- `| #"space-around" `
- `| #"space-evenly" `
- `| #stretch `
- `| #"safe-center" `
- `| #"unsafe-center" `
- `| #inherit `
- `| #initial `
- `| #unset `
- `| #"flex-start" `
`]>`
#### `alignSelf`
- CSS Key: `align-self`
- Type: `AlignContent.t`
#### `justifySelf`
- CSS Key: `justify-self`
- Type: `AlignContent.t`
#### `flexFlow`
- CSS Key: `flex-flow`
- Type: `(FlexDirection.t, FlexWrap.t)`
#### `gap`
- CSS Key: `gap`
- Type: `responsiveProp<[`
- `| #one(Config.spacing)`
- `| #two(Config.t, Config.spacing) `
- `| #inherit`
- `| #initial`
- `| #revert`
- `| #unset`
`]>`
### Border
:::important
Check out the [`Config.radius`](/docs/system-props#configradius) type signature.
:::
#### `borderRadius`
- CSS Key: `border`
- Type: `responsiveProp`
#### `borderTLRadius`
- CSS Key: `border-top-left-radius`
- Type: `responsiveProp`
#### `borderTRRadius`
- CSS Key: `border-top-right-radius`
- Type: `responsiveProp`
#### `borderBLRadius`
- CSS Key: `border-bottom-left-radius`
- Type: `responsiveProp`
#### `borderBRRadius`
- CSS Key: `border-bottom-right-radius`
- Type: `responsiveProp`
:::important
Check out the [`Border.t`](/docs/system-props#bordert) and [`BordeStyle.t`](/docs/system-props/#borderstylet) type signature.
:::
#### `border`
- CSS Key: `border`
- Type: `responsiveProp`
#### `borderTop`
- CSS Key: `border-top`
- Type: `responsiveProp`
#### `borderBottom`
- CSS Key: `border-bottom`
- Type: `responsiveProp`
#### `borderLeft`
- CSS Key: `border-left`
- Type: `responsiveProp`
#### `borderRight`
- CSS Key: `border-right`
- Type: `responsiveProp`
#### `borderTopStyle`
- CSS Key: `border-top-style`
- Type: `responsiveProp`
#### `borderBottomStyle`
- CSS Key: `border-bottom-style`
- Type: `responsiveProp`
#### `borderLeftStyle`
- CSS Key: `border-left-style`
- Type: `responsiveProp`
#### `borderRightStyle`
- CSS Key: `border-right-style`
- Type: `responsiveProp`
#### `borderTopWidth`
- CSS Key: `border-top-width`
- Type: `responsiveProp`
#### `borderBottomWidth`
- CSS Key: `border-bottom-width`
- Type: `responsiveProp`
#### `borderLeftWidth`
- CSS Key: `border-left-width`
- Type: `responsiveProp`
#### `borderRightWidth`
- CSS Key: `border-right-width`
- Type: `responsiveProp`
#### `borderTopColor`
- CSS Key: `border-top-color`
- Type: `responsiveProp`
#### `borderBottomColor`
- CSS Key: `border-bottom-color`
- Type: `responsiveProp`
#### `borderLeftColor`
- CSS Key: `border-left-color`
- Type: `responsiveProp`
#### `borderRightColor`
- CSS Key: `border-right-color`
- Type: `responsiveProp`
### Size
#### `width`
- CSS Key: `width`
- Type: `responsiveProp`
#### `height`
- CSS Key: `height`
- Type: `responsiveProp`
#### `maxW`
- CSS Key: `max-width`
- Type: `responsiveProp`
#### `minW`
- CSS Key: `min-width`
- Type: `responsiveProp`
#### `maxH`
- CSS Key: `max-width`
- Type: `responsiveProp`
#### `minH`
- CSS Key: `min-width`
- Type: `responsiveProp`
:::important
Check out the [`Length.t`](/docs/system-props#lengtht) type signature.
:::
### Texts
#### `fontFamily`
- CSS Key: `font-family`
- Type: `responsiveProp<[`
- `| #custom(array)`
- `| #initial`
- `| #inherit`
`]>`
#### `fontWeight`
- CSS Key: `font-weight`
- Type: `responsiveProp<[`
- `| #normal `
- `| #bold `
- `| #bolder `
- `| #lighter `
- `| #100 `
- `| #200 `
- `| #300 `
- `| #400 `
- `| #500 `
- `| #600 `
- `| #700 `
- `| #800 `
- `| #900 `
- `| #initial `
- `| #inherit`
`]>`
#### `textAlign`
- CSS Key: `text-align`
- Type: `responsiveProp<[#center | #left | #right]>`
#### `letterSpacing`
- CSS Key: `letter-spacing`
- Type: `responsiveProp`
#### `lineHeight`
- CSS Key: `line-height`
- Type: `responsiveProp`
### Position & Placement
#### `position`
- CSS Key: `position`
- Type: `responsiveProp<[ | #static | #relative | #absolute | #fixed | #sticky ]>`
#### `top`
- CSS Key: `top`
- Type: `responsiveProp`
#### `bottom`
- CSS Key: `bottom`
- Type: `responsiveProp`
#### `left`
- CSS Key: `left`
- Type: `responsiveProp`
#### `right`
- CSS Key: `right`
- Type: `responsiveProp`
#### `zIndex`
- CSS Key: `z-index`
- Type: `responsiveProp`
### General
#### `display`
- CSS Key: `display`
- Type: `responsiveProp<[|`
- `| #none `
- `| #inline `
- `| #block `
- `| #"list-item" `
- `| #"inline-block" `
- `| #"inline-table" `
- `| #table `
- `| #"table-cell" `
- `| #"table-column" `
- `| #"table-column-group" `
- `| #"table-footer-group" `
- `| #"table-header-group" `
- `| #"table-row" `
- `| #"table-row-group" `
- `| #flex`
- `| #"inline-flex" `
- `| #grid `
- `| #"inline-grid" `
- `| #"run-in" `
- `| #inherit`
`]>`
#### `boxSizing`
- CSS Key: `box-sizing`
- Type: `responsiveProp<[| #"content-box" | #"border-box" | #initial | #inherit ]>`
#### `color`
- CSS Key: `color`
- Type: `responsiveProp`
#### `bgColor`
- CSS Key: `background-color`
- Type: `responsiveProp`
#### `bgSize`
- CSS Key: `background-size`
- Type: `responsiveProp<[`
- `| #cover`
- `| #contain`
- `| #inherit`
- `| #initial`
- `| #unset`
- `| #auto`
- `| #length(Length.t)`
`]>`
#### `bgPosition`
- CSS Key: `background-position`
- Type: `responsiveProp<[`
-`| #top`
-`| #bottom`
-`| #left`
-`| #right`
-`| #center`
-`| #inherit`
-`| #initial`
-`| #unset`
-`| #length(Length.t)`
`]>`
#### `bgImage`
- CSS Key: `background-image`
- Type: `responsiveProp<[`
-`| #url(string)`
-`| #initial`
-`| #inherit`
`]>`
:::important
Check out the [`Color.t`](/docs/system-props#colort) type signature.
:::
#### `overflow`
- CSS Key: `overflow`
- Type: `responsiveProp<[#hidden | #visible | #scroll | #auto]>`
#### `overflowX`
- CSS Key: `overflow-x`
- Type: `responsiveProp<[#hidden | #visible | #scroll | #auto]>`
#### `overflowY`
- CSS Key: `overflow-y`
- Type: `responsiveProp<[#hidden | #visible | #scroll | #auto]>`
#### `cursor`
- CSS Key: `cursor`
- Type: `responsiveProp<[`
- ` | #auto`
- ` | #default`
- ` | #none`
- ` | #"context-menu"`
- ` | #help`
- ` | #pointer`
- ` | #progress`
- ` | #wait`
- ` | #cell`
- ` | #crosshair`
- ` | #text`
- ` | #"vertical-text"`
- ` | #alias`
- ` | #copy`
- ` | #move`
- ` | #"no-drop"`
- ` | #"not-allowed"`
- ` | #grab`
- ` | #grabbing`
- ` | #"all-scroll"`
- ` | #"col-resize"`
- ` | #"row-resize"`
- ` | #"n-resize"`
- ` | #"e-resize"`
- ` | #"s-resize"`
- ` | #"w-resize"`
- ` | #"ne-resize"`
- ` | #"nw-resize"`
- ` | #"se-resize"`
- ` | #"sw-resize"`
- ` | #"ew-resize"`
- ` | #"ns-resize"`
- ` | #"nesw-resize"`
- ` | #"nwse-resize"`
- ` | #"zoom-in"`
- ` | #"zoom-out"`
`]>`
#### `visibility`
- CSS Key: `visibility`
- Type: `responsiveProp<[#hidden | #visible | #collapse]>`
#### `listStyleType`
- CSS Key: `list-style-type`
- Type: `responsiveProp<`
- `| #disc`
- `| #circle`
- `| #square`
- `| #decimal`
- `| #"lower-alpha"`
- `| #"upper-alpha"`
- `| #"lower-greek"`
- `| #"lower-latin"`
- `| #"upper-latin"`
- `| #"lower-roman"`
- `| #"upper-roman"`
- `| #none`
`]>`
#### `listStylePosition`
- CSS Key: `list-style-position`
- Type: `responsiveProp<`
- `| #inside`
- `| #outside`
`]>`
#### `listStyleImage`
- CSS Key: `list-style-image`
- Type: `responsiveProp<`
- `| #url(string)`
`]>`
#### `listStyle`
- CSS Key: `list-style`
- Type: `responsiveProp<`
- `| #"type"(ListStyleType.t)`
- `| #position(ListStylePosition.t)`
- `| #image(ListStyleImage.t)`
- `| #short(ListStyleType.t, ListStylePosition.t, ListStyleImage.t)`
- `| #inherit`
- `| #initial`
- `| #revert`
- `| #unset`
- `| #none`
`]>`
#### `outlineStyle`
- CSS Key: `outline-style`
- Type: `responsiveProp<`
- `| #none`
- `| #hidden`
- `| #dotted`
- `| #dashed`
- `| #solid`
- `| #double`
- `| #groove`
- `| #ridge`
- `| #inset`
- `| #outset`
`]>`
#### `outline`
- CSS Key: `outline`
- Type: `responsiveProp<`
- `| #short(Length.t, OutlineStyle.t, Color.t)`
- `| #inherit`
- `| #initial`
- `| #unset`
`]>`
#### `textDecorationStyle`
- CSS Key: `text-decoration-style`
- Type: `responsiveProp<[#solid | #double | #dotted | #dashed | #wavy]>`
#### `textDecorationLine`
- CSS Key: `text-decoration-line`
- Type: `responsiveProp<[#none | #underline | #overline | #"line-through" | #blink]>`
#### `textDecoration`
- CSS Key: `text-decoration`
- Type: `responsiveProp<[`
- `| #short(TextDecorationLine.t, Color.t, TextDecorationStyle.t)`
- `| #initial`
- `| #inherit`
- `| #none`
`]>`
#### `transform`
- CSS Key: `transform`
- Type: `responsiveProp`
:::important
Check out the [`Transform.t`](/docs/system-props#transformt) type signature.
:::
## Types reference
### `Config.spacing`
The `Config.spacing` type is customizable, check out its [customization section](/docs/customization#spacing). By default, it's typed as an `int`.
```rescript
type spacing = int
```
### `Config.radius`
The `Config.radius` type is customizable, check out its [customization section](/docs/customization#border-radius). By default, it's typed as an `int`.
```rescript
type radius = int
```
### `Length.t`
Used by props like `width`, `height`, `line-height`, etc:
```rescript
type t = [
| #ch(float)
| #em(float)
| #ex(float)
| #rem(float)
| #vh(float)
| #vw(float)
| #vmin(float)
| #vmax(float)
| #px(int)
| #pxFloat(float)
| #cm(float)
| #mm(float)
| #inch(float)
| #pc(float)
| #pt(int)
| #zero
| #pct(float)
| #add(t, t)
| #sub(t, t)
| #mult(t, t)
| #div(t, t)
]
```
### Using CSS `calc`
```rescript
#rem, 10->#px))]>
...
```
The expression `#add(1.6->#rem, 10->#px)` is equivalent to `calc(1.6rem + 10px)` in plain CSS. You can replace `#add` by `#sub`, `#mult` or `#div` to use another calc operator.
### `BorderStyle.t`
Used by props like `borderLeftStyle`, `borderStyle`, etc:
```rescript
type t = [
| #none
| #hidden
| #dotted
| #dashed
| #solid
| #double
| #groove
| #ridge
| #inset
| #outset
]
```
### `Border.t`
Used by props like `border`, `borderTop`, etc:
```rescript
type t = (Length.t, BorderStyle.t, Color.t)
```
### `Color.t`
Used by props like `border`, `bgColor`, `color`, etc:
```rescript
type t = [
| #rgb(int, int, int)
| #hex(string)
| #transparent
| #currentColor
]
```
### `Transform.t`
Used by `transform`:
```rescript
type t = [
| #translate(Length.t, Length.t)
| #translate3d(Length.t, Length.t, Length.t)
| #translateX(Length.t)
| #translateY(Length.t)
| #translateZ(Length.t)
| #scale(float, float)
| #scale3d(float, float, float)
| #scaleX(float)
| #scaleY(float)
| #scaleZ(float)
| #rotate(Angle.t)
| #rotate3d(float, float, float, Angle.t)
| #rotateX(Angle.t)
| #rotateY(Angle.t)
| #rotateZ(Angle.t)
| #skew(Angle.t, Angle.t)
| #skewX(Angle.t)
| #skewY(Angle.t)
| #perspective(int)
]
```
================================================
FILE: website/docs/use-responsive-value/ResponsiveValueExample.res
================================================
open Ancestor
module Card = {
@react.component
let make = (~color, ~label) =>
#px)]
color=[xs("#fafafa"->#hex)]
bgColor=[xs(color)]>
{label->React.string}
}
@react.component
let make = () => {
let color = Ancestor.useResponsiveValue(
Theme.Colors.black,
[xs(Theme.Colors.gray1), md(Theme.Colors.black)],
)
let label = Ancestor.useResponsiveValue(
"Default",
[
xs("This text appears on xs"),
md("This text text appears on sm"),
lg("This text appears on lg"),
],
)
}
================================================
FILE: website/docs/use-responsive-value/use-responsive-value.md
================================================
---
title: useResponsiveValue(...)
---
import CodeBlock from '@theme/CodeBlock'
import { Wrapper } from '../_helpers'
import ResponsiveValueExampleSource from '!!raw-loader!./ResponsiveValueExample.res'
import { make as ResponsiveValueExample } from './ResponsiveValueExample.bs'
`useResponsiveValue(...)` is a custom hook that returns the value for the current breakpoint. You provide an array of responsive values
and it returns the value for the current breakpoint.
{ResponsiveValueExampleSource}
:::important
Resize your browser to see the responsive values in action.
:::
## API
The hook has the following type signature
```rescript
let useResponsiveValue:(
'value,
ResponsiveValueHook.Styles.responsiveProp<'value>,
) => 'value
```
================================================
FILE: website/docusaurus.config.js
================================================
const theme = require('prism-react-renderer/themes/nightOwl')
/** @type {import('@docusaurus/types').DocusaurusConfig} */
module.exports = {
title: 'Ancestor — UI primitives for ReScript and React',
tagline: '',
url: 'https://ancestor.rescriptbrasil.org',
baseUrl: '/',
onBrokenLinks: 'throw',
onBrokenMarkdownLinks: 'warn',
favicon: 'img/favicon.ico',
organizationName: 'rescriptbr',
projectName: 'ancestor',
themeConfig: {
colorMode: {
defaultMode: 'light',
disableSwitch: true,
},
navbar: {
logo: {
alt: 'Ancestor Logo',
src: 'img/logo-black.svg',
},
items: [
{
type: 'doc',
docId: 'intro',
position: 'left',
label: 'Documentation',
},
{
href: 'https://github.com/rescriptbr/ancestor',
label: 'GitHub',
position: 'right',
},
],
},
footer: {
style: 'dark',
links: [
{
title: 'ReScript Brazil',
items: [
{
label: 'Discord',
href: 'https://discord.gg/wj7Ak9JJtZ',
},
{
label: 'Twitter',
href: 'https://twitter.com/rescriptbr',
},
{
label: 'GitHub',
href: 'https://github.com/rescriptbr',
},
],
},
{
title: 'About',
items: [
{
label: 'Getting Started',
to: '/docs/intro',
},
{
label: 'Docs',
to: '/docs/intro',
},
{
label: 'GitHub',
href: 'https://github.com/rescriptbr/ancestor',
},
],
},
],
copyright: `Copyright © ${new Date().getFullYear()} ReScript Brazil Community, Built with Docusaurus and ReScript.`,
},
prism: {
additionalLanguages: ['rescript'],
theme: theme,
darkTheme: theme,
},
},
presets: [
[
'@docusaurus/preset-classic',
{
docs: {
sidebarPath: require.resolve('./sidebars.js'),
editUrl:
'https://github.com/facebook/docusaurus/edit/master/website/',
},
theme: {
customCss: require.resolve('./src/css/app.css'),
},
},
],
],
}
================================================
FILE: website/package.json
================================================
{
"name": "website",
"version": "0.0.0",
"private": true,
"scripts": {
"rescript:build": "rescript build -with-deps",
"rescript:watch": "rescript build -w",
"rescript:clean": "rescript clean",
"rescript:format": "rescript format",
"docusaurus": "docusaurus",
"start": "docusaurus start",
"build": "yarn rescript:build && docusaurus build",
"swizzle": "docusaurus swizzle",
"deploy": "docusaurus deploy",
"serve": "docusaurus serve",
"clear": "docusaurus clear",
"write-translations": "docusaurus write-translations",
"write-heading-ids": "docusaurus write-heading-ids",
"prettier": "prettier --write 'src/**/*.{js,json,md}'"
},
"dependencies": {
"@docusaurus/core": "2.0.1",
"@docusaurus/preset-classic": "2.0.1",
"@mdx-js/react": "^1.6.21",
"@rescript/react": "0.10.3",
"@rescriptbr/ancestor": "1.0.0-2",
"@svgr/webpack": "^5.5.0",
"clsx": "^1.1.1",
"file-loader": "^6.2.0",
"prettier": "2.3.2",
"prism-react-renderer": "^1.2.1",
"raw-loader": "4.0.2",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"rescript": "9.1.4",
"url-loader": "^4.1.1",
"prismjs": "1.28.0"
},
"browserslist": {
"production": [
">0.5%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {}
}
================================================
FILE: website/sidebars.js
================================================
module.exports = {
docs: [
'intro',
'getting-started',
'customization/customization',
{
type: `category`,
label: `API Reference`,
collapsed: false,
items: [
'system-props',
'api/base',
'api/box',
'api/grid',
'api/hidden',
'api/stack',
'use-responsive-value/use-responsive-value'
],
},
],
}
================================================
FILE: website/src/bindings/Docusaurus.res
================================================
type siteConfig = {title: string}
type docusaurusContext = {siteConfig: siteConfig}
@module("@docusaurus/useDocusaurusContext")
external useDocusaurusContext: unit => docusaurusContext = "default"
module Layout = {
@react.component @module("@theme/Layout")
external make: (~title: string, ~description: string, ~children: React.element) => React.element =
"default"
}
================================================
FILE: website/src/css/app.css
================================================
@import url('https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;700&display=swap');
html, body {
overflow-x: hidden;
}
::selection {
background: #000;
color: #fff;
}
h1,h2,h3,h4,h5,h6,button,a {
font-family: 'DM Sans';
}
/**
* Theming
* */
:root {
--gray-2: #B1B1B1;
--ifm-color-primary: #ff3366;
--ifm-color-primary-dark: rgb(33, 175, 144);
--ifm-color-primary-darker: rgb(31, 165, 136);
--ifm-color-primary-darkest: rgb(26, 136, 112);
--ifm-color-primary-light: rgb(70, 203, 174);
--ifm-color-primary-lighter: rgb(102, 212, 189);
--ifm-color-primary-lightest: rgb(146, 224, 208);
--ifm-code-font-size: 95%;
--ifm-font-family-base: 'DM Sans', sans-serif;
--xxs: 0px;
--xs: 475px;
--sm: 600px;
--md: 920px;
--lg: 1280px;
}
/**
* Footer
* */
.footer--dark {
--ifm-footer-background-color: #000;
}
.footer__copyright {
margin-top: 56px;
}
/*
* Navbar
* **/
@media only screen and (max-width: 995px) {
.navbar__items {
flex-direction: row-reverse;
justify-content: space-between;
}
}
.theme-code-block-highlighted-line {
background-color: rgb(255 255 255 / 7%)!important;
}
================================================
FILE: website/src/helpers/Render.res
================================================
let s = React.string
================================================
FILE: website/src/pages/Home/Home.res
================================================
open Render
@module("./home.module.css") external styles: {..} = "default"
module Memphis = {
module Lines = {
@react.component
let make = (~id) => {
}
}
module Square = {
@react.component
let make = (~id) => {
}
}
module Circle = {
@react.component
let make = (~id) => {
}
}
@react.component
let make = () => {
}
}
module Hero = {
@react.component
let make = () => {
{"Simple, fast and powerful"->s}
{`A suite of UI primitives for ReScript and React with focus on responsiveness.`->s}
}
}
module AboutItem = {
@react.component
let make = (~icon, ~title, ~description) => {
{title->s} {description->s}
}
}
module About = {
@react.component
let make = () => {
}
}
module CodePreview = {
@react.component
let make = () => {
{`Built for ReScript`->s}
{`It's not a set of bindings for an existing library, Ancestor was created from scratch to use with ReScript.`->s}
}
}
module StartUsing = {
@react.component
let make = () => {
{`Start using right now`->s}
{`This project is still beta but also actively maintained. It's used in some production `->s}
{`projects daily and keep breaking changes to a minimum whereever possible.`->s}
{`Let’s start`->s}
}
}
@react.component
let make = () => {
}
let default = make
================================================
FILE: website/src/pages/Home/home.module.css
================================================
.hero--title {
color: #000;
font-family: DM Sans;
font-style: normal;
font-weight: bold;
font-size: 46px;
line-height: 60px;
letter-spacing: -0.07em;
}
.hero--text {
font-family: DM Sans;
font-style: normal;
font-weight: normal;
font-size: 32px;
line-height: 42px;
letter-spacing: -0.04em;
color: var(--gray-2);
}
/*
* About
* */
.about--item > h2 {
font-family: DM Sans;
font-style: normal;
font-weight: bold;
font-size: 24px;
line-height: 31px;
margin: 0;
margin-bottom: 8px;
text-align: center;
}
.about--item > p {
font-family: DM Sans;
font-style: normal;
font-weight: 500;
font-size: 20px;
line-height: 23px;
color: var(--gray-2);
text-align: center;
}
@media only screen and (min-width: 0px) {
.hero {
position: relative;
padding: 124px 32px;
}
.hero--image {
display: none;
}
#lines-1 {
top: 42px;
left: -32px;
position: absolute;
}
#lines-2 {
bottom: 0px;
right: -32px;
position: absolute;
}
#square-1 {
position: absolute;
bottom: 32px;
left: 56px;
}
#circle-1 {
position: absolute;
bottom: 16px;
left: 124px;
}
#square-2 {
position: absolute;
top: 72px;
right: 92px;
}
#circle-2 {
position: absolute;
top: 56px;
right: 56px;
}
.about {
margin: 92px auto;
padding: 0 32px;
}
.about--item {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 56px;
}
.about--row {
display: flex;
flex-direction: column;
}
.about--item > img {
width: 46px;
margin-bottom: 18px;
}
.code-preview {
padding: 32px;
}
.code-preview--texts > h2 {
font-family: DM Sans;
font-style: normal;
font-weight: bold;
font-size: 42px;
line-height: 55px;
letter-spacing: -0.07em;
margin: 0;
margin-bottom: 8px;
}
.code-preview--texts > p {
font-family: DM Sans;
font-style: normal;
font-weight: normal;
font-size: 26px;
line-height: 32px;
color: var(--gray-2);
letter-spacing: -0.06em;
margin: 0;
}
.code-preview--texts {
margin-bottom: 46px;
}
.start-box {
background: #000;
margin: 124px 0;
padding: 32px;
}
.start-box--texts > h2 {
color: white;
margin-bottom: 16px;
font-family: DM Sans;
font-style: normal;
font-weight: bold;
font-size: 32px;
line-height: 32px;
letter-spacing: -0.04em;
}
.start-box--texts > p {
font-family: DM Sans;
font-style: normal;
font-weight: normal;
font-size: 20px;
line-height: 28px;
letter-spacing: -0.04em;
color: var(--gray-2);
}
.start-box > a {
text-decoration: none;
}
.start-box > a > button {
height: 52px;
border-radius: 32px;
width: 192px;
background: #fafafa;
font-family: DM Sans;
font-style: normal;
font-weight: 500;
font-size: 20px;
line-height: 23px;
text-align: center;
letter-spacing: -0.04em;
outline: none;
border: 0;
cursor: pointer;
}
.start-box > a > button:hover {
background: #e4e4e4;
}
}
@media only screen and (min-width: 600px) {
.start-box {
padding: 56px;
}
.hero {
padding: 132px 42px;
}
}
@media only screen and (min-width: 920px) {
.hero {
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
max-width: 1280px;
margin: 0 auto;
}
.hero--image {
display: block;
}
.hero--title-container {
flex-basis: 50%;
z-index: 10;
}
#lines-1 {
top: 72px;
left: -24px;
position: absolute;
}
#lines-2 {
bottom: -56px;
right: -16px;
position: absolute;
}
#square-1 {
position: absolute;
bottom: 56px;
left: 92px;
}
#circle-1 {
position: absolute;
bottom: 32px;
left: 150px;
}
#square-2 {
position: absolute;
top: 72px;
right: 200px;
}
#circle-2 {
position: absolute;
top: 56px;
right: 250px;
}
.about {
max-width: 1280px;
margin: 124px auto;
padding: 0 124px;
}
.about--item {
display: flex;
flex-direction: column;
align-items: center;
flex-basis: 50%;
padding: 0 32px;
}
.about--item:nth-child(1) {
margin-right: 124px;
}
.about--row {
display: flex;
flex-direction: row;
margin-bottom: 72px;
}
.about--item > img {
width: 46px;
margin-bottom: 18px;
}
.code-preview {
padding: 32px;
max-width: 1280px;
margin: 0 auto;
display: flex;
align-items: center;
margin-bottom: 124px;
}
.code-preview--texts {
margin-bottom: 0;
margin-right: 32px;
}
.start-box {
display: flex;
justify-content: space-between;
}
.start-box {
max-width: 1280px;
margin: 224px auto;
display: flex;
align-items: center;
padding: 72px;
margin-bottom: 124px;
}
}
@media only screen and (min-width: 1920px) {
.about--item:nth-child(1) {
margin-right: 224px;
}
}
================================================
FILE: website/src/pages/index.js
================================================
import React from 'react'
import Home from './Home/Home.bs'
export default Home
================================================
FILE: website/src/pages/markdown-page.md
================================================
---
title: Markdown page example
---
# Markdown page example
You don't need React to write simple standalone pages.
================================================
FILE: website/static/.nojekyll
================================================