├── .eslintrc.js
├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── renovate.json
└── workflows
│ └── check.yml
├── .gitignore
├── .nvmrc
├── .prettierrc.js
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── LICENSE
├── README.md
├── babel.config.js
├── lerna.json
├── lint-staged.config.js
├── package.json
├── packages
├── docs
│ ├── CHANGELOG.md
│ ├── babel.config.js
│ ├── next-env.d.ts
│ ├── next.config.js
│ ├── package.json
│ ├── public
│ │ ├── img
│ │ │ ├── favicon@192.png
│ │ │ ├── icon@128.png
│ │ │ ├── icon@192.png
│ │ │ ├── icon@512.png
│ │ │ ├── logo-og.png
│ │ │ └── logo-readme.png
│ │ └── manifest.json
│ ├── src
│ │ ├── components
│ │ │ ├── code
│ │ │ │ ├── code.tsx
│ │ │ │ └── index.tsx
│ │ │ ├── head.tsx
│ │ │ ├── headings.tsx
│ │ │ ├── layout.tsx
│ │ │ └── toggle-color-mode.tsx
│ │ ├── config.ts
│ │ ├── lib
│ │ │ └── plausible.tsx
│ │ ├── pages
│ │ │ ├── _app.tsx
│ │ │ ├── _document.tsx
│ │ │ └── index.md
│ │ └── theme.ts
│ └── tsconfig.json
└── raam
│ ├── .npmignore
│ ├── CHANGELOG.md
│ ├── README.md
│ ├── package.json
│ ├── src
│ ├── flex.tsx
│ ├── index.ts
│ ├── inline.tsx
│ ├── private
│ │ ├── box.ts
│ │ ├── flexbox.ts
│ │ ├── flexgap.ts
│ │ └── types.ts
│ ├── stack.tsx
│ └── wrap.tsx
│ ├── test
│ ├── __snapshots__
│ │ └── index.tsx.snap
│ └── index.tsx
│ └── tsconfig.json
└── yarn.lock
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | parser: "@typescript-eslint/parser",
3 | plugins: ["jsx-a11y"],
4 | extends: [
5 | "plugin:react/recommended",
6 | "plugin:@typescript-eslint/recommended",
7 | "plugin:jsx-a11y/strict",
8 | "plugin:prettier/recommended",
9 | "prettier/react",
10 | "prettier/@typescript-eslint",
11 | ],
12 | parserOptions: {
13 | ecmaVersion: 2018,
14 | sourceType: "module",
15 | ecmaFeatures: {
16 | jsx: true,
17 | },
18 | },
19 | rules: {
20 | "@typescript-eslint/explicit-function-return-type": "off",
21 | "@typescript-eslint/prefer-interface": "off",
22 | "@typescript-eslint/ban-ts-ignore": "off",
23 | "jsx-a11y/label-has-for": "off",
24 | "react/prop-types": "off",
25 | "react/display-name": "off",
26 | },
27 | settings: {
28 | react: {
29 | version: "detect",
30 | },
31 | },
32 | overrides: [
33 | {
34 | files: ["*.js"],
35 | rules: {
36 | "@typescript-eslint/no-var-requires": "off",
37 | },
38 | },
39 | {
40 | files: ["*.d.ts"],
41 | rules: {
42 | "@typescript-eslint/no-unused-vars": "off",
43 | },
44 | },
45 | ],
46 | };
47 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "enabled": false
3 | }
4 |
--------------------------------------------------------------------------------
/.github/workflows/check.yml:
--------------------------------------------------------------------------------
1 | name: Node.js CI
2 |
3 | on:
4 | push:
5 | branches: [main]
6 | pull_request:
7 | branches: [main]
8 |
9 | jobs:
10 | build:
11 | runs-on: ubuntu-latest
12 |
13 | strategy:
14 | matrix:
15 | os:
16 | - ubuntu-latest
17 |
18 | steps:
19 | - uses: actions/checkout@v2
20 | - name: Read .nvmrc
21 | run: echo ::set-output name=NVMRC::$(cat .nvmrc)
22 | id: nvm
23 |
24 | - name: Setup Node.js
25 | uses: actions/setup-node@v2.1.2
26 | with:
27 | node-version: "${{ steps.nvm.outputs.NVMRC }}"
28 | - run: yarn install --frozen-lockfile
29 | - run: yarn lint
30 | - run: yarn test
31 | - run: yarn build
32 | env:
33 | CI: true
34 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .eslintcache
2 | node_modules
3 |
4 | .next
5 | out
6 |
7 | dist
8 | .rts2_cache*
9 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | 13.8.0
2 |
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | trailingComma: "es5"
3 | };
4 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | All notable changes to this project will be documented in this file.
4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5 |
6 | ## [0.2.3](https://github.com/joe-bell/raam/compare/v0.2.2...v0.2.3) (2020-09-07)
7 |
8 | **Note:** Version bump only for package root
9 |
10 | ## [0.2.2](https://github.com/joe-bell/raam/compare/v0.2.1...v0.2.2) (2020-09-07)
11 |
12 | ### Bug Fixes
13 |
14 | - add missing key to Flex child components ([c08d64c](https://github.com/joe-bell/raam/commit/c08d64ccb81da5bd9714dbc401be667c8be2bc06))
15 | - avoid rendering empty children ([b9c9a8d](https://github.com/joe-bell/raam/commit/b9c9a8d6b217733a142a1942afabb38c526c9732))
16 |
17 | ## [0.2.1](https://github.com/joe-bell/raam/compare/v0.2.0...v0.2.1) (2020-06-20)
18 |
19 | ### Bug Fixes
20 |
21 | - add fallback values ([3ee6df6](https://github.com/joe-bell/raam/commit/3ee6df600ec724ee0a6f64ede95305491b5981d6))
22 | - add workaround for type conflict ([b5f0e29](https://github.com/joe-bell/raam/commit/b5f0e29da1814abb9ba4d401b00c706ba95b3506))
23 | - update workflow to reflect branch change ([dae4778](https://github.com/joe-bell/raam/commit/dae47783d4335d208cbd7377d5bae75d88da9243))
24 |
25 | # [0.2.0](https://github.com/joe-bell/raam/compare/v0.1.1...v0.2.0) (2020-04-10)
26 |
27 | ### Features
28 |
29 | - **flex:** use custom system, pass flex item styles to child ([b8c9828](https://github.com/joe-bell/raam/commit/b8c9828be13890a6400c8af18799a4e69df5a31e))
30 |
31 | ## [0.1.1](https://github.com/joe-bell/raam/compare/v0.1.0...v0.1.1) (2020-04-10)
32 |
33 | ### Bug Fixes
34 |
35 | - allow for use without a ThemeProvider ([8b53da7](https://github.com/joe-bell/raam/commit/8b53da75cc3336b7e4131b5374938adce03a1afb))
36 | - spelling error (good spot [@peduarte](https://github.com/peduarte)) ([ed91c1a](https://github.com/joe-bell/raam/commit/ed91c1a5acab525a056e0e42f46a8ad9bd9e81b6))
37 | - update system font stack ([4c39e62](https://github.com/joe-bell/raam/commit/4c39e6229563cff886394b67c94d30289152a5e9))
38 |
39 | # [0.1.0](https://github.com/joe-bell/raam/compare/v0.0.7...v0.1.0) (2020-04-08)
40 |
41 | ### Bug Fixes
42 |
43 | - switch to yarn due to dep conflicts ([380ff35](https://github.com/joe-bell/raam/commit/380ff35c1d079510f2194b99051136da1ed1e564))
44 |
45 | ### Features
46 |
47 | - support strings and numbers ([833e830](https://github.com/joe-bell/raam/commit/833e8309e757616569b9dca97fdb1e8789aee4fc))
48 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | - Using welcoming and inclusive language
18 | - Being respectful of differing viewpoints and experiences
19 | - Gracefully accepting constructive criticism
20 | - Focusing on what is best for the community
21 | - Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | - The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | - Trolling, insulting/derogatory comments, and personal or political attacks
28 | - Public or private harassment
29 | - Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | - Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team on Twitter (@joebell\_). All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Joe Bell
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | > ⚠️ **Deprecated**
2 | >
3 | > Flexbox `gap` is relatively [well-supported](https://caniuse.com/flexbox-gap) now, you should use it instead.
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | raam (estonian) ˈrɑːm n . frame
13 |
14 |
15 |
16 |
17 | Beautifully boring cosmetic-free React.js components for structure and layout.
18 |
19 |
20 |
21 | Read the Docs 📖
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | test: {
4 | presets: ["@babel/env", "@babel/react", "@babel/preset-typescript"],
5 | },
6 | },
7 | };
8 |
--------------------------------------------------------------------------------
/lerna.json:
--------------------------------------------------------------------------------
1 | {
2 | "packages": ["packages/*"],
3 | "version": "0.2.3",
4 | "npmClient": "yarn",
5 | "useWorkspaces": true,
6 | "command": {
7 | "publish": {
8 | "conventionalCommits": true
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/lint-staged.config.js:
--------------------------------------------------------------------------------
1 | const eslint = filenames =>
2 | `eslint --cache --fix --ignore-path .gitignore --fix --ext .js,.jsx,.ts,.tsx ${
3 | !filenames || filenames.length > 10 ? "." : filenames.join(" ")
4 | }`;
5 |
6 | module.exports = {
7 | "**/*.{json,html,css,md,mdx,yml}": filenames =>
8 | filenames.map(filename => `prettier --write '${filename}'`),
9 | "**/*.js?(x)": filenames => eslint(filenames),
10 | "**/*.ts?(x)": () => [`yarn lint:ts`, eslint()],
11 | };
12 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "root",
4 | "scripts": {
5 | "build": "lerna run prebuild && lerna run build",
6 | "clean": "lerna run clean && lerna clean --yes && rimraf node_modules",
7 | "dev": "lerna run dev --parallel",
8 | "lint": "lerna run lint && yarn lint:es -- .",
9 | "lint:es": "eslint --ignore-path .gitignore --fix --ext .js,.jsx,.ts,.tsx",
10 | "lint:ts": "lerna run lint:ts",
11 | "test": "jest",
12 | "commit": "git-cz"
13 | },
14 | "workspaces": [
15 | "packages/*"
16 | ],
17 | "config": {
18 | "commitizen": {
19 | "path": "cz-conventional-changelog"
20 | }
21 | },
22 | "husky": {
23 | "hooks": {
24 | "pre-commit": "lint-staged"
25 | }
26 | },
27 | "jest": {
28 | "testMatch": [
29 | "**/packages/**/test/*.{ts,tsx}"
30 | ],
31 | "snapshotSerializers": [
32 | "jest-emotion"
33 | ]
34 | },
35 | "devDependencies": {
36 | "@babel/core": "7.11.6",
37 | "@babel/preset-env": "7.11.5",
38 | "@babel/preset-react": "7.10.4",
39 | "@babel/preset-typescript": "7.10.4",
40 | "@types/node": "14.11.5",
41 | "@types/react": "16.9.51",
42 | "@types/styled-system": "5.1.10",
43 | "@types/theme-ui": "0.3.4",
44 | "@typescript-eslint/eslint-plugin": "2.34.0",
45 | "@typescript-eslint/parser": "2.34.0",
46 | "babel-jest": "26.3.0",
47 | "barrelsby": "2.2.0",
48 | "commitizen": "4.1.2",
49 | "csstype": "3.0.3",
50 | "cz-conventional-changelog": "3.3.0",
51 | "eslint": "6.8.0",
52 | "eslint-config-prettier": "6.12.0",
53 | "eslint-plugin-jsx-a11y": "6.3.1",
54 | "eslint-plugin-prettier": "3.1.4",
55 | "eslint-plugin-react": "7.21.2",
56 | "husky": "4.3.0",
57 | "jest": "26.4.2",
58 | "jest-emotion": "10.0.32",
59 | "lerna": "3.22.1",
60 | "lint-staged": "10.2.13",
61 | "microbundle": "0.12.4",
62 | "prettier": "1.19.1",
63 | "react-test-renderer": "16.13.1",
64 | "rimraf": "3.0.2",
65 | "typescript": "4.0.2"
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/packages/docs/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | All notable changes to this project will be documented in this file.
4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5 |
6 | ## [0.2.3](https://github.com/joe-bell/raam/compare/v0.2.2...v0.2.3) (2020-09-07)
7 |
8 | **Note:** Version bump only for package docs
9 |
10 | ## [0.2.2](https://github.com/joe-bell/raam/compare/v0.2.1...v0.2.2) (2020-09-07)
11 |
12 | **Note:** Version bump only for package docs
13 |
14 | ## [0.2.1](https://github.com/joe-bell/raam/compare/v0.2.0...v0.2.1) (2020-06-20)
15 |
16 | **Note:** Version bump only for package docs
17 |
18 | # [0.2.0](https://github.com/joe-bell/raam/compare/v0.1.1...v0.2.0) (2020-04-10)
19 |
20 | ### Features
21 |
22 | - **flex:** use custom system, pass flex item styles to child ([b8c9828](https://github.com/joe-bell/raam/commit/b8c9828be13890a6400c8af18799a4e69df5a31e))
23 |
24 | ## [0.1.1](https://github.com/joe-bell/raam/compare/v0.1.0...v0.1.1) (2020-04-10)
25 |
26 | ### Bug Fixes
27 |
28 | - spelling error (good spot [@peduarte](https://github.com/peduarte)) ([ed91c1a](https://github.com/joe-bell/raam/commit/ed91c1a5acab525a056e0e42f46a8ad9bd9e81b6))
29 | - update system font stack ([4c39e62](https://github.com/joe-bell/raam/commit/4c39e6229563cff886394b67c94d30289152a5e9))
30 |
31 | # [0.1.0](https://github.com/joe-bell/raam/compare/v0.0.7...v0.1.0) (2020-04-08)
32 |
33 | ### Bug Fixes
34 |
35 | - switch to yarn due to dep conflicts ([380ff35](https://github.com/joe-bell/raam/commit/380ff35c1d079510f2194b99051136da1ed1e564))
36 |
--------------------------------------------------------------------------------
/packages/docs/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: ["next/babel"],
3 | };
4 |
--------------------------------------------------------------------------------
/packages/docs/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
--------------------------------------------------------------------------------
/packages/docs/next.config.js:
--------------------------------------------------------------------------------
1 | const remarkSlug = require("remark-slug");
2 |
3 | const withMDX = require("@next/mdx")({
4 | extension: /\.mdx?$/,
5 | options: {
6 | remarkPlugins: [remarkSlug],
7 | },
8 | });
9 |
10 | module.exports = withMDX({
11 | pageExtensions: ["ts", "tsx", "md", "mdx"],
12 | });
13 |
--------------------------------------------------------------------------------
/packages/docs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "name": "docs",
4 | "version": "0.2.3",
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build && next export",
8 | "clean": "rimraf {.next,out}",
9 | "lint:ts": "npx tsc --noEmit",
10 | "test": "echo \"Error: no test specified\" && exit 1",
11 | "start": "next start",
12 | "vercel": "yarn --cwd ../../ build && yarn build"
13 | },
14 | "dependencies": {
15 | "@mdx-js/loader": "1.6.18",
16 | "@next/mdx": "9.5.3",
17 | "next": "9.5.5",
18 | "next-google-fonts": "1.2.1",
19 | "prism-react-renderer": "1.1.1",
20 | "raam": "^0.2.3",
21 | "react": "16.13.1",
22 | "react-dom": "16.13.1",
23 | "react-live": "2.2.2",
24 | "remark-slug": "6.0.0",
25 | "theme-ui": "0.3.1"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/packages/docs/public/img/favicon@192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joe-bell/raam/59da4826bcc97e660fae1549b3d4085dc48857cf/packages/docs/public/img/favicon@192.png
--------------------------------------------------------------------------------
/packages/docs/public/img/icon@128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joe-bell/raam/59da4826bcc97e660fae1549b3d4085dc48857cf/packages/docs/public/img/icon@128.png
--------------------------------------------------------------------------------
/packages/docs/public/img/icon@192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joe-bell/raam/59da4826bcc97e660fae1549b3d4085dc48857cf/packages/docs/public/img/icon@192.png
--------------------------------------------------------------------------------
/packages/docs/public/img/icon@512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joe-bell/raam/59da4826bcc97e660fae1549b3d4085dc48857cf/packages/docs/public/img/icon@512.png
--------------------------------------------------------------------------------
/packages/docs/public/img/logo-og.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joe-bell/raam/59da4826bcc97e660fae1549b3d4085dc48857cf/packages/docs/public/img/logo-og.png
--------------------------------------------------------------------------------
/packages/docs/public/img/logo-readme.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joe-bell/raam/59da4826bcc97e660fae1549b3d4085dc48857cf/packages/docs/public/img/logo-readme.png
--------------------------------------------------------------------------------
/packages/docs/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "raam",
3 | "description": "Beautifully boring cosmetic-free React.js components for structure and layout",
4 | "icons": [
5 | {
6 | "src": "/img/icon@128.png",
7 | "type": "image/png",
8 | "sizes": "128x128"
9 | },
10 | {
11 | "src": "/img/icon@192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "/img/icon@512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": "/",
22 | "display": "standalone",
23 | "scope": "/"
24 | }
25 |
--------------------------------------------------------------------------------
/packages/docs/src/components/code/code.tsx:
--------------------------------------------------------------------------------
1 | /** @jsx jsx */
2 | import { jsx, Box, Heading, Link } from "theme-ui";
3 | import Highlight, { defaultProps } from "prism-react-renderer";
4 | import { LiveProvider, LiveEditor, LiveError, LivePreview } from "react-live";
5 | import * as Raam from "raam";
6 |
7 | const Code = ({ children, className, live }) => {
8 | const language = className.replace(/language-/, "");
9 | if (live) {
10 | return (
11 |
19 | "/** @jsx jsx */" + code}
22 | scope={{ jsx, Box, Heading, Link, ...Raam }}
23 | >
24 |
32 |
36 |
46 |
47 |
48 | );
49 | }
50 | return (
51 |
52 | {({ className, style, tokens, getLineProps, getTokenProps }) => (
53 |
54 | {tokens.map((line, i) => (
55 |
56 | {line.map((token, key) => (
57 |
58 | ))}
59 |
60 | ))}
61 |
62 | )}
63 |
64 | );
65 | };
66 |
67 | export default Code;
68 |
--------------------------------------------------------------------------------
/packages/docs/src/components/code/index.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import dynamic from "next/dynamic";
3 |
4 | const CodeDynamic = dynamic(() => import("./code"));
5 |
6 | export default props => ;
7 |
--------------------------------------------------------------------------------
/packages/docs/src/components/head.tsx:
--------------------------------------------------------------------------------
1 | /** @jsx jsx */
2 | import * as React from "react";
3 | import NextHead from "next/head";
4 | import GoogleFonts from "next-google-fonts";
5 | import { jsx, useThemeUI } from "theme-ui";
6 | import config from "../config";
7 | import { PlausibleSnippet } from "../lib/plausible";
8 |
9 | const Head: React.FC = () => {
10 | const { theme } = useThemeUI();
11 |
12 | return (
13 |
14 |
15 |
16 |
17 |
18 |
19 | {config.meta.title}
20 |
21 | {process.env.NODE_ENV === "production" && }
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | );
47 | };
48 |
49 | export default Head;
50 |
--------------------------------------------------------------------------------
/packages/docs/src/components/headings.tsx:
--------------------------------------------------------------------------------
1 | /** @jsx jsx */
2 | import { jsx, NavLink } from "theme-ui";
3 |
4 | const heading = Tag => props => {
5 | if (!props.id) return ;
6 | return (
7 |
8 |
17 | {props.children}
18 |
19 |
20 | );
21 | };
22 |
23 | const components = {
24 | h1: heading("h1"),
25 | h2: heading("h2"),
26 | h3: heading("h3"),
27 | h4: heading("h4"),
28 | h5: heading("h5"),
29 | h6: heading("h6"),
30 | };
31 |
32 | export default components;
33 |
--------------------------------------------------------------------------------
/packages/docs/src/components/layout.tsx:
--------------------------------------------------------------------------------
1 | /** @jsx jsx */
2 | import * as React from "react";
3 | import { jsx, Box, Container, Heading, NavLink } from "theme-ui";
4 | import { Wrap } from "raam";
5 | import Head from "./head";
6 | import ToggleColorMode from "./toggle-color-mode";
7 | import config from "../config";
8 |
9 | const border = {
10 | border: "thick",
11 | borderColor: "border",
12 | };
13 |
14 | const gap = 3;
15 |
16 | const Layout: React.FC = ({ children }) => (
17 | <>
18 |
22 |
23 |
24 |
25 |
26 |
27 | );
28 | }
29 | }
30 |
31 | export default RaamDocument;
32 |
--------------------------------------------------------------------------------
/packages/docs/src/pages/index.md:
--------------------------------------------------------------------------------
1 | > ⚠️ **Deprecated**
2 | >
3 | > Flexbox `gap` is relatively [well-supported](https://caniuse.com/flexbox-gap) now, you should use it instead.
4 |
5 | > **raam** (estonian) ˈrɑːm _**n**._ frame.
6 |
7 | **Beautifully boring cosmetic-free [React.js][reactjs] components for structure and layout.**
8 |
9 | Use **raam**'s layout primitives to build resilient theme-driven designs fast.
10 |
11 | ---
12 |
13 | ## Components
14 |
15 | 1. [Wrap](#wrap)
16 | 2. [Inline](#inline)
17 | 3. [Stack](#stack)
18 | 4. [Feature Candidates](#feature-candidates)
19 |
20 | ### Wrap
21 |
22 | A [Flex](#flex)-based layout that renders and 'wraps' children inline spaced
23 | by the defined [`gap`](#configuration).
24 |
25 | Here [`gap`](#configuration) is accessing the value from `theme.space[3]`.
26 |
27 | ```jsx live=true
28 | // import { Wrap } from "raam";
29 | // import { Box } from "your-components";
30 |
31 |
32 | {Array.from({ length: 32 }).map((item, i) => (
33 | 0 && `hue-rotate(${i * 2}deg)`,
40 | }}
41 | />
42 | ))}
43 |
44 | ```
45 |
46 | #### Responsive
47 |
48 | As the [`gap`](#configuration) prop is powered by [Styled System][styled-system], you have the ability to create responsive styles.
49 |
50 | Here [`gap`](#configuration) is accessing the value from `theme.space[3]`, then
51 | `theme.space[4]` at `breakpoint[1]` etc.
52 |
53 | ```jsx live=true
54 | // import { Wrap } from "raam";
55 | // import { Box } from "your-components";
56 |
57 |
58 | {Array.from({ length: 32 }).map((item, i) => (
59 | 0 && `hue-rotate(${i * 2}deg)`,
66 | }}
67 | />
68 | ))}
69 |
70 | ```
71 |
72 | #### Example
73 |
74 | Let's take a look at a more real-world example; a "tag"-list at the bottom of an article:
75 |
76 | - Padding is added to the [`Stack`](#stack), [not the `Wrap` directly](#caveats).
77 | - [`Wrap`](#wrap) uses the [shared configuration](#configuration) to render our `ul` with `li` children:
78 |
79 | ```jsx live=true
80 | // import { Stack, Wrap } from "raam";
81 | // import { Box, Heading, Link } from "your-components";
82 |
83 |
84 | Tags
85 |
86 |
87 | {Array.from({ length: 8 }, (v, k) => k + 1).map(item => (
88 |
89 | Tag {item}
90 |
91 | ))}
92 |
93 |
94 | ```
95 |
96 | ### Inline
97 |
98 | If you'd rather let items flow elegantly in a single line, make use of `Inline`.
99 |
100 | Scroll behaviour can be removed with an `overflow: 'hidden'`.
101 |
102 | ```jsx live=true
103 | // import { Inline } from "raam";
104 | // import { Box } from "your-components";
105 |
106 |
107 | {Array.from({ length: 32 }).map((item, i) => (
108 | 0 && `hue-rotate(${i * 2}deg)`,
115 | }}
116 | />
117 | ))}
118 |
119 | ```
120 |
121 | or with some more chaotic values…
122 |
123 | ```jsx live=true
124 | // import { Inline } from "raam";
125 | // import { Box } from "your-components";
126 |
127 | () => {
128 | const size = () => `${Math.floor(Math.random() * 4) + 1}rem`;
129 |
130 | return (
131 |
132 | {Array.from({ length: 32 }).map((item, i) => (
133 | 0 && `hue-rotate(${i * 2}deg)`,
140 | }}
141 | />
142 | ))}
143 |
144 | );
145 | };
146 | ```
147 |
148 | ### Stack
149 |
150 | Popularised by [Seek's "Braid"](https://github.com/seek-oss/braid-design-system), a [Flex](#flex)-based layout that renders children on top of each other, spaced by the defined [`gap`](#configuration).
151 |
152 | ```jsx live=true
153 | // import { Stack } from "raam";
154 | // import { Box } from "your-components";
155 |
156 |
157 | {Array.from({ length: 4 }).map((item, i) => (
158 |
159 | ))}
160 |
161 | ```
162 |
163 | > "Hold up, why don't you just…"
164 | >
165 | > - _"…use `display: grid;`"_
166 | > Grid is fantastic for page layouts, but has its caveats for a 'simple' `Stack`:
167 | > - It doesn't behave reliably for all elements (e.g. [`fieldset`](https://bugs.chromium.org/p/chromium/issues/detail?id=854565))
168 | > - Can lead to ['blow out'](https://css-tricks.com/preventing-a-grid-blowout/).
169 | > - _"…make `Inline` and `Stack` one component"?_
170 | > [↓](#flex)
171 |
172 | ### Flex
173 |
174 | A `display: flex;`-based layout primitive that aims to address the `gap`.
175 |
176 | `Stack`, `Wrap` and `Inline` are all effectively "presets" of Flex. Don't like that? It's OK, you can use `Flex` directly without opinionated defaults.
177 |
178 | #### Caveats
179 |
180 | > **TL;DR:** Mind the Gap
181 |
182 | At the time of **raam**'s release, usage of `gap` in flex-based layouts is only supported by Firefox. To address this shortcoming, fallbacks are used:
183 |
184 | 1. In `nowrap` based layouts, margins are used in a single direction excluding the first-child.
185 | 2. In `wrap` based layouts, negative margins are used on the outer component to counteract margins inside.
186 | It will **not** affect adjacent margins, **but** you will experience issues if you try to adjust it directly - instead consider wrapping the element.
187 |
188 | ### Feature Candidates
189 |
190 | #### Article
191 |
192 | A layout primitive to control vertical rhythm and flow for typographic content.
193 |
194 | ---
195 |
196 | ## Getting Started
197 |
198 | ### Installation
199 |
200 | > **⚠ WIP **
201 | >
202 | > This project is in development and comes with caveats:
203 | >
204 | > 1. Only supports React.js apps with [Emotion][emotion] **or** [Theme UI][theme-ui] pre-installed (for the time being).
205 | > 2. Prone to regular unannounced changes.
206 |
207 | `npm i raam --save`
208 | or
209 | `yarn add raam`
210 |
211 | [reactjs]: https://reactjs.org
212 | [theme-ui]: https://theme-ui.com/
213 |
214 | ### Configuration
215 |
216 | All components use a shared set of `props`:
217 |
218 | - `gap`: a dynamic prop that aims to resolve the lack of `gap` support for `display: flex;` in most browsers.
219 |
220 | It accepts a key from `theme.space` (as a string or number), but if that's not found it'll render the provided string (e.g. `em` or `rem`) or number as a `px` value.
221 |
222 | - [Color](https://styled-system.com/table#color), [Space](https://styled-system.com/table#space) and [Flexbox](https://styled-system.com/table#flexbox) (excluding `order`, `alignSelf` and `justifySelf`) props from [Styled System][styled-system].
223 | - `as`: change the HTML element rendered ([via Emotion](https://emotion.sh/docs/styled#as-prop)).
224 |
225 | **raam** makes an **opinionated** choice on how to render a
226 | component's children based on the element provided:
227 |
228 | | `as` | `children` rendered `as` |
229 | | :-------------- | :---------------------------------- |
230 | | `div` (default) | `div` |
231 | | `ol` | `li` (with `list-style-type` reset) |
232 | | `ul` | `li` (with `list-style-type` reset) |
233 | | `span` | `span` |
234 | | `p` | `span` |
235 | | `h1`-`h6` | `span` |
236 |
237 | - `css`: apply styles to the component ([via Emotion](https://emotion.sh/docs/css-prop)).
238 |
239 | **Note**: Use with caution, modifying the margin/padding may not behave as expected.
240 |
241 | - `sx`: apply **themed** styles to the component ([via Theme UI](https://theme-ui.com/sx-prop/)).
242 |
243 | **Note**: Heavily recommended to install [Theme UI][theme-ui] before using. As with `css`, use with caution.
244 |
245 | ### Acknowledgements
246 |
247 | Without these projects/people, this project wouldn't exist…
248 |
249 | - [**OOCSS** - Nicole Sullivan](https://github.com/stubbornella/oocss/wiki)
250 | - [**Braid** - Seek](https://github.com/seek-oss/braid-design-system)
251 |
252 | [emotion]: https://emotion.sh/
253 | [reactjs]: https://reactjs.org
254 | [styled-system]: https://styled-system.com/
255 | [theme-ui]: https://theme-ui.com/
256 |
--------------------------------------------------------------------------------
/packages/docs/src/theme.ts:
--------------------------------------------------------------------------------
1 | const black = "#000";
2 | const white = "#FFF";
3 |
4 | const colors = {
5 | text: black,
6 | textCode: "#f6f6f6",
7 | background: white,
8 | backgroundCode: black,
9 | border: black,
10 | primary: "#0072CE",
11 | muted: "#f6f6f6",
12 | error: "#e23636",
13 | };
14 |
15 | const colorModes = {
16 | modes: {
17 | dark: {
18 | text: white,
19 | background: black,
20 | border: white,
21 | muted: "#1C1B20",
22 | },
23 | },
24 | };
25 |
26 | const space = [0, 4, 8, 16, 32, 64, 128, 256, 512];
27 |
28 | const borderStyles = {
29 | thick: "solid",
30 | };
31 |
32 | const borderWidths = {
33 | thick: space[1],
34 | };
35 |
36 | const theme = {
37 | colors: {
38 | ...colors,
39 | ...colorModes,
40 | },
41 | space,
42 | fonts: {
43 | body: '"Inter", sans-serif',
44 | heading: "inherit",
45 | monospace: "Menlo, monospace",
46 | },
47 | fontSizes: [12, 14, 16, 20, 24, 32, 48, 64, 96],
48 | fontWeights: {
49 | body: 400,
50 | heading: 700,
51 | bold: 700,
52 | },
53 | layout: {
54 | container: {
55 | maxWidth: 960,
56 | px: 3,
57 | },
58 | },
59 | lineHeights: {
60 | body: 1.5,
61 | heading: 1.125,
62 | },
63 | borderStyles,
64 | borderWidths,
65 | borders: {
66 | thick: `${borderWidths.thick}px ${borderStyles.thick}`,
67 | },
68 | styles: {
69 | root: {
70 | fontFamily: "body",
71 | lineHeight: "body",
72 | fontWeight: "body",
73 | },
74 | blockquote: {
75 | marginX: 0,
76 | padding: 1,
77 | paddingLeft: 3,
78 | borderLeft: "primary",
79 | borderColor: "primary",
80 | bg: "muted",
81 | },
82 | h1: {
83 | color: "text",
84 | fontFamily: "heading",
85 | lineHeight: "heading",
86 | fontWeight: "heading",
87 | fontSize: 6,
88 | },
89 | h2: {
90 | color: "text",
91 | fontFamily: "heading",
92 | lineHeight: "heading",
93 | fontWeight: "heading",
94 | fontSize: 5,
95 | },
96 | h3: {
97 | color: "text",
98 | fontFamily: "heading",
99 | lineHeight: "heading",
100 | fontWeight: "heading",
101 | fontSize: 4,
102 | },
103 | h4: {
104 | color: "text",
105 | fontFamily: "heading",
106 | lineHeight: "heading",
107 | fontWeight: "heading",
108 | fontSize: 3,
109 | },
110 | h5: {
111 | color: "text",
112 | fontFamily: "heading",
113 | lineHeight: "heading",
114 | fontWeight: "heading",
115 | fontSize: 2,
116 | },
117 | h6: {
118 | color: "text",
119 | fontFamily: "heading",
120 | lineHeight: "heading",
121 | fontWeight: "heading",
122 | fontSize: 1,
123 | },
124 | p: {
125 | color: "text",
126 | fontFamily: "body",
127 | fontWeight: "body",
128 | lineHeight: "body",
129 | },
130 | a: {
131 | color: "primary",
132 | },
133 | pre: {
134 | fontFamily: "monospace",
135 | overflowX: "auto",
136 | code: {
137 | color: "inherit",
138 | },
139 | },
140 | code: {
141 | fontFamily: "monospace",
142 | fontSize: "inherit",
143 | },
144 | inlineCode: {
145 | fontFamily: "monospace",
146 | fontSize: 1,
147 | padding: 1,
148 | backgroundColor: "muted",
149 | },
150 | table: {
151 | width: "100%",
152 | borderCollapse: "separate",
153 | borderSpacing: 0,
154 | },
155 | th: {
156 | padding: 1,
157 | textAlign: "left",
158 | borderBottomStyle: "solid",
159 | },
160 | td: {
161 | padding: 1,
162 | textAlign: "left",
163 | borderBottomStyle: "solid",
164 | borderBottomWidth: 2,
165 | },
166 | hr: {
167 | border: 0,
168 | borderBottom: "divider",
169 | },
170 | img: {
171 | maxWidth: "100%",
172 | },
173 | },
174 | };
175 |
176 | export default theme;
177 |
--------------------------------------------------------------------------------
/packages/docs/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": false,
8 | "forceConsistentCasingInFileNames": true,
9 | "noEmit": true,
10 | "esModuleInterop": true,
11 | "module": "esnext",
12 | "moduleResolution": "node",
13 | "resolveJsonModule": true,
14 | "isolatedModules": true,
15 | "jsx": "preserve"
16 | },
17 | "exclude": ["node_modules"],
18 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
19 | }
20 |
--------------------------------------------------------------------------------
/packages/raam/.npmignore:
--------------------------------------------------------------------------------
1 | !dist
2 | test
--------------------------------------------------------------------------------
/packages/raam/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | All notable changes to this project will be documented in this file.
4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5 |
6 | ## [0.2.3](https://github.com/joe-bell/raam/compare/v0.2.2...v0.2.3) (2020-09-07)
7 |
8 | **Note:** Version bump only for package raam
9 |
10 | ## [0.2.2](https://github.com/joe-bell/raam/compare/v0.2.1...v0.2.2) (2020-09-07)
11 |
12 | ### Bug Fixes
13 |
14 | - add missing key to Flex child components ([c08d64c](https://github.com/joe-bell/raam/commit/c08d64ccb81da5bd9714dbc401be667c8be2bc06))
15 | - avoid rendering empty children ([b9c9a8d](https://github.com/joe-bell/raam/commit/b9c9a8d6b217733a142a1942afabb38c526c9732))
16 |
17 | ## [0.2.1](https://github.com/joe-bell/raam/compare/v0.2.0...v0.2.1) (2020-06-20)
18 |
19 | ### Bug Fixes
20 |
21 | - add fallback values ([3ee6df6](https://github.com/joe-bell/raam/commit/3ee6df600ec724ee0a6f64ede95305491b5981d6))
22 | - add workaround for type conflict ([b5f0e29](https://github.com/joe-bell/raam/commit/b5f0e29da1814abb9ba4d401b00c706ba95b3506))
23 |
24 | # [0.2.0](https://github.com/joe-bell/raam/compare/v0.1.1...v0.2.0) (2020-04-10)
25 |
26 | ### Features
27 |
28 | - **flex:** use custom system, pass flex item styles to child ([b8c9828](https://github.com/joe-bell/raam/commit/b8c9828be13890a6400c8af18799a4e69df5a31e))
29 |
30 | ## [0.1.1](https://github.com/joe-bell/raam/compare/v0.1.0...v0.1.1) (2020-04-10)
31 |
32 | ### Bug Fixes
33 |
34 | - allow for use without a ThemeProvider ([8b53da7](https://github.com/joe-bell/raam/commit/8b53da75cc3336b7e4131b5374938adce03a1afb))
35 |
36 | # [0.1.0](https://github.com/joe-bell/raam/compare/v0.0.7...v0.1.0) (2020-04-08)
37 |
38 | ### Bug Fixes
39 |
40 | - switch to yarn due to dep conflicts ([380ff35](https://github.com/joe-bell/raam/commit/380ff35c1d079510f2194b99051136da1ed1e564))
41 |
42 | ### Features
43 |
44 | - support strings and numbers ([833e830](https://github.com/joe-bell/raam/commit/833e8309e757616569b9dca97fdb1e8789aee4fc))
45 |
--------------------------------------------------------------------------------
/packages/raam/README.md:
--------------------------------------------------------------------------------
1 | # raam
2 |
3 | [See the Docs](https://raam.joebell.co.uk)
4 |
--------------------------------------------------------------------------------
/packages/raam/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "raam",
3 | "version": "0.2.3",
4 | "description": "Beautifully boring cosmetic-free React.js components for structure and layout.",
5 | "source": "src/index.ts",
6 | "main": "dist/index.js",
7 | "module": "dist/index.esm.js",
8 | "typings": "dist/index.d.ts",
9 | "files": [
10 | "dist",
11 | "README.md"
12 | ],
13 | "scripts": {
14 | "prebuild": "barrelsby --delete --directory src --exclude private",
15 | "build": "microbundle --no-compress --jsx React.createElement --tsconfig tsconfig.json",
16 | "clean": "rimraf {dist,.rts2*}",
17 | "lint:ts": "npx tsc --noEmit",
18 | "dev": "npm run build -- watch",
19 | "test": "echo \"Error: no test specified\" && exit 1"
20 | },
21 | "repository": {
22 | "type": "git",
23 | "url": "git+https://github.com/joe-bell/raam.git"
24 | },
25 | "author": "Joe Bell (https://joebell.co.uk)",
26 | "license": "ISC",
27 | "bugs": {
28 | "url": "https://github.com/joe-bell/raam/issues"
29 | },
30 | "homepage": "https://github.com/joe-bell/raam#readme",
31 | "peerDependencies": {
32 | "@emotion/core": ">= 10.0.0",
33 | "@emotion/styled": ">= 10.0.0",
34 | "@theme-ui/css": ">= 0.3.1",
35 | "react": ">= 16.8.0"
36 | },
37 | "dependencies": {
38 | "@styled-system/color": "5.1.2",
39 | "@styled-system/core": "5.1.2",
40 | "@styled-system/should-forward-prop": "5.1.5",
41 | "@styled-system/space": "5.1.2"
42 | },
43 | "devDependencies": {
44 | "@emotion/core": "10.0.35",
45 | "@emotion/styled": "10.0.27",
46 | "@theme-ui/css": "0.3.1",
47 | "emotion-theming": "10.0.27",
48 | "react": "16.13.1"
49 | },
50 | "gitHead": "a6e19e2884b0d784a69a7c8af29cae7008a5cb16"
51 | }
52 |
--------------------------------------------------------------------------------
/packages/raam/src/flex.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { Box, BoxProps } from "./private/box";
3 | import { GapProp } from "./private/types";
4 |
5 | const determineChild = (parent: FlexProps["as"]) =>
6 | typeof parent === "string"
7 | ? {
8 | ul: "li",
9 | ol: "li",
10 | span: "span",
11 | p: "span",
12 | h1: "span",
13 | h2: "span",
14 | h3: "span",
15 | h4: "span",
16 | h5: "span",
17 | h6: "span",
18 | }[parent] || "div"
19 | : parent;
20 |
21 | export type FlexProps = BoxProps & GapProp;
22 |
23 | export const Flex = React.forwardRef(
24 | (
25 | {
26 | as = "div",
27 | gap,
28 | children,
29 | flex,
30 | flexBasis,
31 | flexGrow,
32 | flexShrink,
33 | flexDirection = "row",
34 | flexWrap = "nowrap",
35 | ...props
36 | },
37 | ref
38 | ) => (
39 |
52 | {React.Children.toArray(children).map((child, i) => (
53 |
70 | {child}
71 |
72 | ))}
73 |
74 | )
75 | );
76 |
--------------------------------------------------------------------------------
/packages/raam/src/index.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * @file Automatically generated by barrelsby.
3 | */
4 |
5 | export * from "./flex";
6 | export * from "./inline";
7 | export * from "./stack";
8 | export * from "./wrap";
9 |
--------------------------------------------------------------------------------
/packages/raam/src/inline.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { FlexProps, Flex } from "./flex";
3 |
4 | export type InlineProps = FlexProps;
5 |
6 | export const Inline = React.forwardRef(
7 | (
8 | { gap = 3, alignItems = "center", flexDirection = "row", ...props },
9 | ref
10 | ) => (
11 |
18 | )
19 | );
20 |
--------------------------------------------------------------------------------
/packages/raam/src/private/box.ts:
--------------------------------------------------------------------------------
1 | import styled from "@emotion/styled";
2 | import { InterpolationWithTheme } from "@emotion/core";
3 | import { css } from "@theme-ui/css";
4 | import { createShouldForwardProp } from "@styled-system/should-forward-prop";
5 | import { compose } from "@styled-system/core";
6 | import space from "@styled-system/space";
7 | import color from "@styled-system/color";
8 | import flexbox, { FlexboxProps } from "./flexbox";
9 | import flexgap, { FlexGapProps } from "./flexgap";
10 | import { Assign, ColorProps, SpaceProps, SxProps, SxStyleProp } from "./types";
11 |
12 | export type BoxOwnProps = {
13 | as?: React.ElementType;
14 | css?: InterpolationWithTheme;
15 | } & SxProps &
16 | ColorProps &
17 | FlexboxProps &
18 | SpaceProps;
19 |
20 | export type BoxPrivateProps = {
21 | __css?: SxStyleProp;
22 | } & FlexGapProps;
23 |
24 | export type BoxProps = Assign<
25 | React.ComponentPropsWithoutRef<"div">,
26 | BoxOwnProps
27 | >;
28 |
29 | const reset = props =>
30 | (typeof props.as === "string" &&
31 | {
32 | /**
33 | * Override browser defaults.
34 | */
35 | ul: { paddingLeft: 0 },
36 | /**
37 | * Ensure any list-items are rendered without bullets.
38 | * Adding a zero-width space in the content to prevent VoiceOver disable.
39 | */
40 | li: {
41 | listStyleType: "none",
42 | "&:before": {
43 | position: "absolute",
44 | content: '"\\200B"',
45 | },
46 | },
47 | }[props.as]) ||
48 | {};
49 |
50 | export const Box = styled("div", {
51 | shouldForwardProp: createShouldForwardProp([
52 | ...space.propNames,
53 | ...color.propNames,
54 | ...flexbox.propNames,
55 | ...flexgap.propNames,
56 | ]),
57 | // Add color override to prevent incompatible collisions
58 | // https://github.com/emotion-js/emotion/issues/1272
59 | })([
60 | {
61 | boxSizing: "border-box",
62 | margin: 0,
63 | minWidth: 0,
64 | },
65 | props => [
66 | props.__css && css(props.__css)(props.theme),
67 | props.as && reset(props),
68 | props.sx && css(props.sx)(props.theme),
69 | props.css,
70 | ],
71 | compose(space, color, flexbox, flexgap),
72 | ]);
73 |
--------------------------------------------------------------------------------
/packages/raam/src/private/flexbox.ts:
--------------------------------------------------------------------------------
1 | import { system } from "@styled-system/core";
2 | import { DefaultFlexboxProps } from "./types";
3 |
4 | export type FlexboxProps = Omit<
5 | DefaultFlexboxProps,
6 | "alignSelf" | "justifySelf" | "order"
7 | >;
8 |
9 | type FlexboxSystem = {
10 | [FlexboxProperty in keyof FlexboxProps]: boolean;
11 | };
12 |
13 | const config: FlexboxSystem = {
14 | alignItems: true,
15 | alignContent: true,
16 | justifyItems: true,
17 | justifyContent: true,
18 | flexWrap: true,
19 | flexDirection: true,
20 | // Flex Item
21 | flex: true,
22 | flexBasis: true,
23 | flexGrow: true,
24 | flexShrink: true,
25 | };
26 |
27 | const flexbox = system(config);
28 |
29 | export default flexbox;
30 |
--------------------------------------------------------------------------------
/packages/raam/src/private/flexgap.ts:
--------------------------------------------------------------------------------
1 | import { system } from "@styled-system/core";
2 | import { FlexboxProps } from "./flexbox";
3 | import { GapValue } from "./types";
4 |
5 | export type FlexGapProps = {
6 | index?: number;
7 | flexParent?: FlexboxProps;
8 | flexChild?: any;
9 | gapOffset?: GapValue;
10 | gapTop?: GapValue;
11 | gapRight?: GapValue;
12 | gapBottom?: GapValue;
13 | gapLeft?: GapValue;
14 | overflow?: GapValue;
15 | overflowX?: GapValue;
16 | };
17 |
18 | const isNumber = n => typeof n === "number" && !isNaN(n);
19 |
20 | const isWrapped = (flexWrap: string) => (flexWrap === "nowrap" ? false : true);
21 | const isColumn = (flexDirection: string) =>
22 | ["column", "column-reverse"].includes(flexDirection);
23 | const isRow = (flexDirection: string) =>
24 | ["row", "row-reverse"].includes(flexDirection);
25 |
26 | const transformGapOffset = (value, scale, props) => {
27 | const themeValue = (scale && scale[value]) || value;
28 |
29 | const offsetValue = isNumber(themeValue)
30 | ? -themeValue / 2
31 | : `calc(-${themeValue} / 2)`;
32 |
33 | return props.flexWrap && isWrapped(props.flexWrap) ? offsetValue : undefined;
34 | };
35 |
36 | const transformGap = (value, scale, props, property) => {
37 | const themeValue = (scale && scale[value]) || value;
38 |
39 | if (props.flexParent && isWrapped(props.flexParent.flexWrap)) {
40 | return isNumber(themeValue) ? themeValue / 2 : `calc(${themeValue} / 2)`;
41 | }
42 |
43 | /* This is disgusting but it works for now,I'll try to come back to it */
44 | if (
45 | props.flexParent &&
46 | props.index > 0 &&
47 | ((property === "marginTop" && isColumn(props.flexParent.flexDirection)) ||
48 | (property === "marginLeft" && isRow(props.flexParent.flexDirection)))
49 | ) {
50 | return themeValue;
51 | }
52 |
53 | return undefined;
54 | };
55 |
56 | type Config = {
57 | [key in keyof FlexGapProps]: {
58 | property: string;
59 | scale?: string;
60 | defaultScale?: number[];
61 | transform: (value: unknown, scale: unknown, props: any) => void;
62 | };
63 | };
64 |
65 | const space = {
66 | scale: "space",
67 | // from @styled-system/space
68 | defaultScale: [0, 4, 8, 16, 32, 64, 128, 256, 512],
69 | };
70 |
71 | const config: Config = {
72 | gapOffset: {
73 | property: "margin",
74 | ...space,
75 | transform: transformGapOffset,
76 | },
77 | gapTop: {
78 | property: "marginTop",
79 | ...space,
80 | transform: (value, scale, props) =>
81 | transformGap(value, scale, props, "marginTop"),
82 | },
83 | gapRight: {
84 | property: "marginRight",
85 | ...space,
86 | transform: (value, scale, props) =>
87 | transformGap(value, scale, props, "marginRight"),
88 | },
89 | gapBottom: {
90 | property: "marginBottom",
91 | ...space,
92 | transform: (value, scale, props) =>
93 | transformGap(value, scale, props, "marginBottom"),
94 | },
95 | gapLeft: {
96 | property: "marginLeft",
97 | ...space,
98 | transform: (value, scale, props) =>
99 | transformGap(value, scale, props, "marginLeft"),
100 | },
101 | flexChild: {
102 | property: "flex",
103 | transform: (value, scale, props) => {
104 | if (props.flexParent && isRow(props.flexParent.flexDirection)) {
105 | return value || "0 0 auto";
106 | }
107 |
108 | return value;
109 | },
110 | },
111 | overflow: {
112 | property: "overflow",
113 | transform: (value, scale, props) =>
114 | value && value !== null && isWrapped(props.flexWrap)
115 | ? "hidden"
116 | : undefined,
117 | },
118 | overflowX: {
119 | property: "overflowX",
120 | transform: (value, scale, props) =>
121 | value &&
122 | value !== null &&
123 | !isWrapped(props.flexWrap) &&
124 | isRow(props.flexDirection)
125 | ? "auto"
126 | : undefined,
127 | },
128 | };
129 |
130 | export const flexgap = system(config);
131 |
132 | export default flexgap;
133 |
--------------------------------------------------------------------------------
/packages/raam/src/private/types.ts:
--------------------------------------------------------------------------------
1 | import { ResponsiveValue } from "styled-system";
2 |
3 | // Sourced from: @types/theme-ui
4 | export type Assign = {
5 | [P in keyof (T & U)]: P extends keyof T
6 | ? T[P]
7 | : P extends keyof U
8 | ? U[P]
9 | : never;
10 | };
11 |
12 | export type GapValue = ResponsiveValue;
13 |
14 | export type GapProp = {
15 | /**
16 | * The gutter between items.
17 | */
18 | gap?: GapValue;
19 | };
20 |
21 | /**
22 | * Because these dependencies aren't being directly used, and just for typings,
23 | * I'm exporting them from here.
24 | */
25 | export {
26 | ColorProps,
27 | FlexboxProps as DefaultFlexboxProps,
28 | SpaceProps,
29 | Theme,
30 | ThemeValue,
31 | } from "styled-system";
32 | export { SxStyleProp, SxProps } from "theme-ui";
33 |
--------------------------------------------------------------------------------
/packages/raam/src/stack.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { FlexProps, Flex } from "./flex";
3 |
4 | export type StackProps = FlexProps;
5 |
6 | export const Stack = React.forwardRef(
7 | ({ gap = 3, flexDirection = "column", ...props }, ref) => (
8 |
9 | )
10 | );
11 |
--------------------------------------------------------------------------------
/packages/raam/src/wrap.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { FlexProps, Flex } from "./flex";
3 |
4 | export type WrapProps = FlexProps;
5 |
6 | export const Wrap = React.forwardRef(
7 | (
8 | {
9 | alignItems = "center",
10 | flexDirection = "row",
11 | flexWrap = "wrap",
12 | gap = 3,
13 | justifyContent = "flex-start",
14 | ...props
15 | },
16 | ref
17 | ) => (
18 |
27 | )
28 | );
29 |
--------------------------------------------------------------------------------
/packages/raam/test/__snapshots__/index.tsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Flex renders 1`] = `
4 | .emotion-3 {
5 | box-sizing: border-box;
6 | margin: 0;
7 | min-width: 0;
8 | display: -webkit-box;
9 | display: -webkit-flex;
10 | display: -ms-flexbox;
11 | display: flex;
12 | -webkit-flex-direction: row;
13 | -ms-flex-direction: row;
14 | flex-direction: row;
15 | -webkit-flex-wrap: nowrap;
16 | -ms-flex-wrap: nowrap;
17 | flex-wrap: nowrap;
18 | }
19 |
20 | .emotion-0 {
21 | box-sizing: border-box;
22 | margin: 0;
23 | min-width: 0;
24 | position: relative;
25 | -webkit-flex: 0 0 auto;
26 | -ms-flex: 0 0 auto;
27 | flex: 0 0 auto;
28 | }
29 |
30 |
33 |
36 |
37 | Item 1
38 |
39 |
40 |
43 |
44 | Item 2
45 |
46 |
47 |
50 |
51 | Item 3
52 |
53 |
54 |
55 | `;
56 |
57 | exports[`Flex renders an array of children 1`] = `
58 | .emotion-3 {
59 | box-sizing: border-box;
60 | margin: 0;
61 | min-width: 0;
62 | display: -webkit-box;
63 | display: -webkit-flex;
64 | display: -ms-flexbox;
65 | display: flex;
66 | -webkit-flex-direction: row;
67 | -ms-flex-direction: row;
68 | flex-direction: row;
69 | -webkit-flex-wrap: nowrap;
70 | -ms-flex-wrap: nowrap;
71 | flex-wrap: nowrap;
72 | }
73 |
74 | .emotion-0 {
75 | box-sizing: border-box;
76 | margin: 0;
77 | min-width: 0;
78 | position: relative;
79 | -webkit-flex: 0 0 auto;
80 | -ms-flex: 0 0 auto;
81 | flex: 0 0 auto;
82 | }
83 |
84 |
87 |
90 | Item 1
91 |
92 |
95 | Item 2
96 |
97 |
100 | Item 3
101 |
102 |
103 | `;
104 |
105 | exports[`Flex renders children as list-items 1`] = `
106 | Array [
107 | .emotion-3 {
108 | box-sizing: border-box;
109 | margin: 0;
110 | min-width: 0;
111 | display: -webkit-box;
112 | display: -webkit-flex;
113 | display: -ms-flexbox;
114 | display: flex;
115 | padding-left: 0;
116 | -webkit-flex-direction: row;
117 | -ms-flex-direction: row;
118 | flex-direction: row;
119 | -webkit-flex-wrap: nowrap;
120 | -ms-flex-wrap: nowrap;
121 | flex-wrap: nowrap;
122 | }
123 |
124 | .emotion-0 {
125 | box-sizing: border-box;
126 | margin: 0;
127 | min-width: 0;
128 | position: relative;
129 | list-style-type: none;
130 | -webkit-flex: 0 0 auto;
131 | -ms-flex: 0 0 auto;
132 | flex: 0 0 auto;
133 | }
134 |
135 | .emotion-0:before {
136 | position: absolute;
137 | content: "\\200B";
138 | }
139 |
140 | ,
171 | .emotion-3 {
172 | box-sizing: border-box;
173 | margin: 0;
174 | min-width: 0;
175 | display: -webkit-box;
176 | display: -webkit-flex;
177 | display: -ms-flexbox;
178 | display: flex;
179 | -webkit-flex-direction: row;
180 | -ms-flex-direction: row;
181 | flex-direction: row;
182 | -webkit-flex-wrap: nowrap;
183 | -ms-flex-wrap: nowrap;
184 | flex-wrap: nowrap;
185 | }
186 |
187 | .emotion-0 {
188 | box-sizing: border-box;
189 | margin: 0;
190 | min-width: 0;
191 | position: relative;
192 | list-style-type: none;
193 | -webkit-flex: 0 0 auto;
194 | -ms-flex: 0 0 auto;
195 | flex: 0 0 auto;
196 | }
197 |
198 | .emotion-0:before {
199 | position: absolute;
200 | content: "\\200B";
201 | }
202 |
203 |
206 |
209 |
212 | Item 1
213 |
214 |
215 |
218 |
221 | Item 2
222 |
223 |
224 |
227 |
230 | Item 3
231 |
232 |
233 | ,
234 | ]
235 | `;
236 |
237 | exports[`Flex renders children with span elements 1`] = `
238 | Array [
239 | .emotion-3 {
240 | box-sizing: border-box;
241 | margin: 0;
242 | min-width: 0;
243 | display: -webkit-box;
244 | display: -webkit-flex;
245 | display: -ms-flexbox;
246 | display: flex;
247 | -webkit-flex-direction: row;
248 | -ms-flex-direction: row;
249 | flex-direction: row;
250 | -webkit-flex-wrap: nowrap;
251 | -ms-flex-wrap: nowrap;
252 | flex-wrap: nowrap;
253 | }
254 |
255 | .emotion-0 {
256 | box-sizing: border-box;
257 | margin: 0;
258 | min-width: 0;
259 | position: relative;
260 | -webkit-flex: 0 0 auto;
261 | -ms-flex: 0 0 auto;
262 | flex: 0 0 auto;
263 | }
264 |
265 |
268 |
271 |
274 | Item 1
275 |
276 |
277 |
280 |
283 | Item 2
284 |
285 |
286 |
289 |
292 | Item 3
293 |
294 |
295 | ,
296 | .emotion-3 {
297 | box-sizing: border-box;
298 | margin: 0;
299 | min-width: 0;
300 | display: -webkit-box;
301 | display: -webkit-flex;
302 | display: -ms-flexbox;
303 | display: flex;
304 | -webkit-flex-direction: row;
305 | -ms-flex-direction: row;
306 | flex-direction: row;
307 | -webkit-flex-wrap: nowrap;
308 | -ms-flex-wrap: nowrap;
309 | flex-wrap: nowrap;
310 | }
311 |
312 | .emotion-0 {
313 | box-sizing: border-box;
314 | margin: 0;
315 | min-width: 0;
316 | position: relative;
317 | -webkit-flex: 0 0 auto;
318 | -ms-flex: 0 0 auto;
319 | flex: 0 0 auto;
320 | }
321 |
322 |
325 |
328 |
331 | Item 1
332 |
333 |
334 |
337 |
340 | Item 2
341 |
342 |
343 |
346 |
349 | Item 3
350 |
351 |
352 |
,
353 | .emotion-3 {
354 | box-sizing: border-box;
355 | margin: 0;
356 | min-width: 0;
357 | display: -webkit-box;
358 | display: -webkit-flex;
359 | display: -ms-flexbox;
360 | display: flex;
361 | -webkit-flex-direction: row;
362 | -ms-flex-direction: row;
363 | flex-direction: row;
364 | -webkit-flex-wrap: nowrap;
365 | -ms-flex-wrap: nowrap;
366 | flex-wrap: nowrap;
367 | }
368 |
369 | .emotion-0 {
370 | box-sizing: border-box;
371 | margin: 0;
372 | min-width: 0;
373 | position: relative;
374 | -webkit-flex: 0 0 auto;
375 | -ms-flex: 0 0 auto;
376 | flex: 0 0 auto;
377 | }
378 |
379 | ,
410 | .emotion-3 {
411 | box-sizing: border-box;
412 | margin: 0;
413 | min-width: 0;
414 | display: -webkit-box;
415 | display: -webkit-flex;
416 | display: -ms-flexbox;
417 | display: flex;
418 | -webkit-flex-direction: row;
419 | -ms-flex-direction: row;
420 | flex-direction: row;
421 | -webkit-flex-wrap: nowrap;
422 | -ms-flex-wrap: nowrap;
423 | flex-wrap: nowrap;
424 | }
425 |
426 | .emotion-0 {
427 | box-sizing: border-box;
428 | margin: 0;
429 | min-width: 0;
430 | position: relative;
431 | -webkit-flex: 0 0 auto;
432 | -ms-flex: 0 0 auto;
433 | flex: 0 0 auto;
434 | }
435 |
436 | ,
467 | .emotion-3 {
468 | box-sizing: border-box;
469 | margin: 0;
470 | min-width: 0;
471 | display: -webkit-box;
472 | display: -webkit-flex;
473 | display: -ms-flexbox;
474 | display: flex;
475 | -webkit-flex-direction: row;
476 | -ms-flex-direction: row;
477 | flex-direction: row;
478 | -webkit-flex-wrap: nowrap;
479 | -ms-flex-wrap: nowrap;
480 | flex-wrap: nowrap;
481 | }
482 |
483 | .emotion-0 {
484 | box-sizing: border-box;
485 | margin: 0;
486 | min-width: 0;
487 | position: relative;
488 | -webkit-flex: 0 0 auto;
489 | -ms-flex: 0 0 auto;
490 | flex: 0 0 auto;
491 | }
492 |
493 | ,
524 | .emotion-3 {
525 | box-sizing: border-box;
526 | margin: 0;
527 | min-width: 0;
528 | display: -webkit-box;
529 | display: -webkit-flex;
530 | display: -ms-flexbox;
531 | display: flex;
532 | -webkit-flex-direction: row;
533 | -ms-flex-direction: row;
534 | flex-direction: row;
535 | -webkit-flex-wrap: nowrap;
536 | -ms-flex-wrap: nowrap;
537 | flex-wrap: nowrap;
538 | }
539 |
540 | .emotion-0 {
541 | box-sizing: border-box;
542 | margin: 0;
543 | min-width: 0;
544 | position: relative;
545 | -webkit-flex: 0 0 auto;
546 | -ms-flex: 0 0 auto;
547 | flex: 0 0 auto;
548 | }
549 |
550 | ,
581 | .emotion-3 {
582 | box-sizing: border-box;
583 | margin: 0;
584 | min-width: 0;
585 | display: -webkit-box;
586 | display: -webkit-flex;
587 | display: -ms-flexbox;
588 | display: flex;
589 | -webkit-flex-direction: row;
590 | -ms-flex-direction: row;
591 | flex-direction: row;
592 | -webkit-flex-wrap: nowrap;
593 | -ms-flex-wrap: nowrap;
594 | flex-wrap: nowrap;
595 | }
596 |
597 | .emotion-0 {
598 | box-sizing: border-box;
599 | margin: 0;
600 | min-width: 0;
601 | position: relative;
602 | -webkit-flex: 0 0 auto;
603 | -ms-flex: 0 0 auto;
604 | flex: 0 0 auto;
605 | }
606 |
607 | ,
638 | .emotion-3 {
639 | box-sizing: border-box;
640 | margin: 0;
641 | min-width: 0;
642 | display: -webkit-box;
643 | display: -webkit-flex;
644 | display: -ms-flexbox;
645 | display: flex;
646 | -webkit-flex-direction: row;
647 | -ms-flex-direction: row;
648 | flex-direction: row;
649 | -webkit-flex-wrap: nowrap;
650 | -ms-flex-wrap: nowrap;
651 | flex-wrap: nowrap;
652 | }
653 |
654 | .emotion-0 {
655 | box-sizing: border-box;
656 | margin: 0;
657 | min-width: 0;
658 | position: relative;
659 | -webkit-flex: 0 0 auto;
660 | -ms-flex: 0 0 auto;
661 | flex: 0 0 auto;
662 | }
663 |
664 | ,
695 | ]
696 | `;
697 |
698 | exports[`Flex style props renders with customised flexbox props 1`] = `
699 | .emotion-3 {
700 | box-sizing: border-box;
701 | margin: 0;
702 | min-width: 0;
703 | display: -webkit-box;
704 | display: -webkit-flex;
705 | display: -ms-flexbox;
706 | display: flex;
707 | overflow: hidden;
708 | margin: -32px;
709 | -webkit-flex-direction: column;
710 | -ms-flex-direction: column;
711 | flex-direction: column;
712 | -webkit-flex-wrap: wrap;
713 | -ms-flex-wrap: wrap;
714 | flex-wrap: wrap;
715 | -webkit-align-content: flex-end;
716 | -ms-flex-line-pack: end;
717 | align-content: flex-end;
718 | -webkit-align-items: center;
719 | -webkit-box-align: center;
720 | -ms-flex-align: center;
721 | align-items: center;
722 | -webkit-box-pack: center;
723 | -webkit-justify-content: center;
724 | -ms-flex-pack: center;
725 | justify-content: center;
726 | justify-items: stretch;
727 | }
728 |
729 | .emotion-0 {
730 | box-sizing: border-box;
731 | margin: 0;
732 | min-width: 0;
733 | position: relative;
734 | margin-top: 32px;
735 | margin-right: 32px;
736 | margin-bottom: 32px;
737 | margin-left: 32px;
738 | -webkit-flex: 1 1 auto;
739 | -ms-flex: 1 1 auto;
740 | flex: 1 1 auto;
741 | -webkit-flex-basis: 100px;
742 | -ms-flex-preferred-size: 100px;
743 | flex-basis: 100px;
744 | -webkit-box-flex: 2;
745 | -webkit-flex-grow: 2;
746 | -ms-flex-positive: 2;
747 | flex-grow: 2;
748 | -webkit-flex-shrink: 1;
749 | -ms-flex-negative: 1;
750 | flex-shrink: 1;
751 | }
752 |
753 |
756 |
759 |
760 | Item 1
761 |
762 |
763 |
766 |
767 | Item 2
768 |
769 |
770 |
773 |
774 | Item 3
775 |
776 |
777 |
778 | `;
779 |
780 | exports[`Flex style props renders with defined gap 1`] = `
781 | .emotion-0 {
782 | box-sizing: border-box;
783 | margin: 0;
784 | min-width: 0;
785 | position: relative;
786 | -webkit-flex: 0 0 auto;
787 | -ms-flex: 0 0 auto;
788 | flex: 0 0 auto;
789 | }
790 |
791 | .emotion-3 {
792 | box-sizing: border-box;
793 | margin: 0;
794 | min-width: 0;
795 | display: -webkit-box;
796 | display: -webkit-flex;
797 | display: -ms-flexbox;
798 | display: flex;
799 | overflow-x: auto;
800 | -webkit-flex-direction: row;
801 | -ms-flex-direction: row;
802 | flex-direction: row;
803 | -webkit-flex-wrap: nowrap;
804 | -ms-flex-wrap: nowrap;
805 | flex-wrap: nowrap;
806 | }
807 |
808 | .emotion-1 {
809 | box-sizing: border-box;
810 | margin: 0;
811 | min-width: 0;
812 | position: relative;
813 | margin-left: 64px;
814 | -webkit-flex: 0 0 auto;
815 | -ms-flex: 0 0 auto;
816 | flex: 0 0 auto;
817 | }
818 |
819 |
822 |
825 |
826 | Item 1
827 |
828 |
829 |
832 |
833 | Item 2
834 |
835 |
836 |
839 |
840 | Item 3
841 |
842 |
843 |
844 | `;
845 |
846 | exports[`Flex style props renders with defined theme gap (emotion) 1`] = `
847 | .emotion-0 {
848 | box-sizing: border-box;
849 | margin: 0;
850 | min-width: 0;
851 | position: relative;
852 | -webkit-flex: 0 0 auto;
853 | -ms-flex: 0 0 auto;
854 | flex: 0 0 auto;
855 | }
856 |
857 | .emotion-3 {
858 | box-sizing: border-box;
859 | margin: 0;
860 | min-width: 0;
861 | display: -webkit-box;
862 | display: -webkit-flex;
863 | display: -ms-flexbox;
864 | display: flex;
865 | overflow-x: auto;
866 | -webkit-flex-direction: row;
867 | -ms-flex-direction: row;
868 | flex-direction: row;
869 | -webkit-flex-wrap: nowrap;
870 | -ms-flex-wrap: nowrap;
871 | flex-wrap: nowrap;
872 | }
873 |
874 | .emotion-1 {
875 | box-sizing: border-box;
876 | margin: 0;
877 | min-width: 0;
878 | position: relative;
879 | margin-left: 64px;
880 | -webkit-flex: 0 0 auto;
881 | -ms-flex: 0 0 auto;
882 | flex: 0 0 auto;
883 | }
884 |
885 |
888 |
891 |
892 | Item 1
893 |
894 |
895 |
898 |
899 | Item 2
900 |
901 |
902 |
905 |
906 | Item 3
907 |
908 |
909 |
910 | `;
911 |
912 | exports[`Flex style props renders with defined theme gap (theme-ui) 1`] = `
913 | .emotion-0 {
914 | box-sizing: border-box;
915 | margin: 0;
916 | min-width: 0;
917 | position: relative;
918 | -webkit-flex: 0 0 auto;
919 | -ms-flex: 0 0 auto;
920 | flex: 0 0 auto;
921 | }
922 |
923 | .emotion-3 {
924 | box-sizing: border-box;
925 | margin: 0;
926 | min-width: 0;
927 | display: -webkit-box;
928 | display: -webkit-flex;
929 | display: -ms-flexbox;
930 | display: flex;
931 | overflow-x: auto;
932 | -webkit-flex-direction: row;
933 | -ms-flex-direction: row;
934 | flex-direction: row;
935 | -webkit-flex-wrap: nowrap;
936 | -ms-flex-wrap: nowrap;
937 | flex-wrap: nowrap;
938 | }
939 |
940 | .emotion-1 {
941 | box-sizing: border-box;
942 | margin: 0;
943 | min-width: 0;
944 | position: relative;
945 | margin-left: 64px;
946 | -webkit-flex: 0 0 auto;
947 | -ms-flex: 0 0 auto;
948 | flex: 0 0 auto;
949 | }
950 |
951 |
954 |
957 |
958 | Item 1
959 |
960 |
961 |
964 |
965 | Item 2
966 |
967 |
968 |
971 |
972 | Item 3
973 |
974 |
975 |
976 | `;
977 |
978 | exports[`Inline renders 1`] = `
979 | .emotion-0 {
980 | box-sizing: border-box;
981 | margin: 0;
982 | min-width: 0;
983 | position: relative;
984 | -webkit-flex: 0 0 auto;
985 | -ms-flex: 0 0 auto;
986 | flex: 0 0 auto;
987 | }
988 |
989 | .emotion-3 {
990 | box-sizing: border-box;
991 | margin: 0;
992 | min-width: 0;
993 | display: -webkit-box;
994 | display: -webkit-flex;
995 | display: -ms-flexbox;
996 | display: flex;
997 | overflow-x: auto;
998 | -webkit-flex-direction: row;
999 | -ms-flex-direction: row;
1000 | flex-direction: row;
1001 | -webkit-flex-wrap: nowrap;
1002 | -ms-flex-wrap: nowrap;
1003 | flex-wrap: nowrap;
1004 | -webkit-align-items: center;
1005 | -webkit-box-align: center;
1006 | -ms-flex-align: center;
1007 | align-items: center;
1008 | }
1009 |
1010 | .emotion-1 {
1011 | box-sizing: border-box;
1012 | margin: 0;
1013 | min-width: 0;
1014 | position: relative;
1015 | margin-left: 32px;
1016 | -webkit-flex: 0 0 auto;
1017 | -ms-flex: 0 0 auto;
1018 | flex: 0 0 auto;
1019 | }
1020 |
1021 |
1024 |
1027 | Item 1
1028 |
1029 |
1032 | Item 2
1033 |
1034 |
1037 | Item 3
1038 |
1039 |
1040 | `;
1041 |
1042 | exports[`Inline renders with defined theme gap (emotion) 1`] = `
1043 | .emotion-0 {
1044 | box-sizing: border-box;
1045 | margin: 0;
1046 | min-width: 0;
1047 | position: relative;
1048 | -webkit-flex: 0 0 auto;
1049 | -ms-flex: 0 0 auto;
1050 | flex: 0 0 auto;
1051 | }
1052 |
1053 | .emotion-3 {
1054 | box-sizing: border-box;
1055 | margin: 0;
1056 | min-width: 0;
1057 | display: -webkit-box;
1058 | display: -webkit-flex;
1059 | display: -ms-flexbox;
1060 | display: flex;
1061 | overflow-x: auto;
1062 | -webkit-flex-direction: row;
1063 | -ms-flex-direction: row;
1064 | flex-direction: row;
1065 | -webkit-flex-wrap: nowrap;
1066 | -ms-flex-wrap: nowrap;
1067 | flex-wrap: nowrap;
1068 | -webkit-align-items: center;
1069 | -webkit-box-align: center;
1070 | -ms-flex-align: center;
1071 | align-items: center;
1072 | }
1073 |
1074 | .emotion-1 {
1075 | box-sizing: border-box;
1076 | margin: 0;
1077 | min-width: 0;
1078 | position: relative;
1079 | margin-left: 32px;
1080 | -webkit-flex: 0 0 auto;
1081 | -ms-flex: 0 0 auto;
1082 | flex: 0 0 auto;
1083 | }
1084 |
1085 |
1088 |
1091 | Item 1
1092 |
1093 |
1096 | Item 2
1097 |
1098 |
1101 | Item 3
1102 |
1103 |
1104 | `;
1105 |
1106 | exports[`Inline renders with defined theme gap (theme-ui) 1`] = `
1107 | .emotion-0 {
1108 | box-sizing: border-box;
1109 | margin: 0;
1110 | min-width: 0;
1111 | position: relative;
1112 | -webkit-flex: 0 0 auto;
1113 | -ms-flex: 0 0 auto;
1114 | flex: 0 0 auto;
1115 | }
1116 |
1117 | .emotion-3 {
1118 | box-sizing: border-box;
1119 | margin: 0;
1120 | min-width: 0;
1121 | display: -webkit-box;
1122 | display: -webkit-flex;
1123 | display: -ms-flexbox;
1124 | display: flex;
1125 | overflow-x: auto;
1126 | -webkit-flex-direction: row;
1127 | -ms-flex-direction: row;
1128 | flex-direction: row;
1129 | -webkit-flex-wrap: nowrap;
1130 | -ms-flex-wrap: nowrap;
1131 | flex-wrap: nowrap;
1132 | -webkit-align-items: center;
1133 | -webkit-box-align: center;
1134 | -ms-flex-align: center;
1135 | align-items: center;
1136 | }
1137 |
1138 | .emotion-1 {
1139 | box-sizing: border-box;
1140 | margin: 0;
1141 | min-width: 0;
1142 | position: relative;
1143 | margin-left: 32px;
1144 | -webkit-flex: 0 0 auto;
1145 | -ms-flex: 0 0 auto;
1146 | flex: 0 0 auto;
1147 | }
1148 |
1149 |
1152 |
1155 | Item 1
1156 |
1157 |
1160 | Item 2
1161 |
1162 |
1165 | Item 3
1166 |
1167 |
1168 | `;
1169 |
1170 | exports[`Stack renders 1`] = `
1171 | .emotion-3 {
1172 | box-sizing: border-box;
1173 | margin: 0;
1174 | min-width: 0;
1175 | display: -webkit-box;
1176 | display: -webkit-flex;
1177 | display: -ms-flexbox;
1178 | display: flex;
1179 | -webkit-flex-direction: column;
1180 | -ms-flex-direction: column;
1181 | flex-direction: column;
1182 | -webkit-flex-wrap: nowrap;
1183 | -ms-flex-wrap: nowrap;
1184 | flex-wrap: nowrap;
1185 | }
1186 |
1187 | .emotion-0 {
1188 | box-sizing: border-box;
1189 | margin: 0;
1190 | min-width: 0;
1191 | position: relative;
1192 | }
1193 |
1194 | .emotion-1 {
1195 | box-sizing: border-box;
1196 | margin: 0;
1197 | min-width: 0;
1198 | position: relative;
1199 | margin-top: 32px;
1200 | }
1201 |
1202 |
1205 |
1208 | Item 1
1209 |
1210 |
1213 | Item 2
1214 |
1215 |
1218 | Item 3
1219 |
1220 |
1221 | `;
1222 |
1223 | exports[`Stack renders with defined theme gap (emotion) 1`] = `
1224 | .emotion-3 {
1225 | box-sizing: border-box;
1226 | margin: 0;
1227 | min-width: 0;
1228 | display: -webkit-box;
1229 | display: -webkit-flex;
1230 | display: -ms-flexbox;
1231 | display: flex;
1232 | -webkit-flex-direction: column;
1233 | -ms-flex-direction: column;
1234 | flex-direction: column;
1235 | -webkit-flex-wrap: nowrap;
1236 | -ms-flex-wrap: nowrap;
1237 | flex-wrap: nowrap;
1238 | }
1239 |
1240 | .emotion-0 {
1241 | box-sizing: border-box;
1242 | margin: 0;
1243 | min-width: 0;
1244 | position: relative;
1245 | }
1246 |
1247 | .emotion-1 {
1248 | box-sizing: border-box;
1249 | margin: 0;
1250 | min-width: 0;
1251 | position: relative;
1252 | margin-top: 32px;
1253 | }
1254 |
1255 |
1258 |
1261 | Item 1
1262 |
1263 |
1266 | Item 2
1267 |
1268 |
1271 | Item 3
1272 |
1273 |
1274 | `;
1275 |
1276 | exports[`Stack renders with defined theme gap (theme-ui) 1`] = `
1277 | .emotion-3 {
1278 | box-sizing: border-box;
1279 | margin: 0;
1280 | min-width: 0;
1281 | display: -webkit-box;
1282 | display: -webkit-flex;
1283 | display: -ms-flexbox;
1284 | display: flex;
1285 | -webkit-flex-direction: column;
1286 | -ms-flex-direction: column;
1287 | flex-direction: column;
1288 | -webkit-flex-wrap: nowrap;
1289 | -ms-flex-wrap: nowrap;
1290 | flex-wrap: nowrap;
1291 | }
1292 |
1293 | .emotion-0 {
1294 | box-sizing: border-box;
1295 | margin: 0;
1296 | min-width: 0;
1297 | position: relative;
1298 | }
1299 |
1300 | .emotion-1 {
1301 | box-sizing: border-box;
1302 | margin: 0;
1303 | min-width: 0;
1304 | position: relative;
1305 | margin-top: 32px;
1306 | }
1307 |
1308 |
1311 |
1314 | Item 1
1315 |
1316 |
1319 | Item 2
1320 |
1321 |
1324 | Item 3
1325 |
1326 |
1327 | `;
1328 |
1329 | exports[`Wrap renders 1`] = `
1330 | .emotion-3 {
1331 | box-sizing: border-box;
1332 | margin: 0;
1333 | min-width: 0;
1334 | display: -webkit-box;
1335 | display: -webkit-flex;
1336 | display: -ms-flexbox;
1337 | display: flex;
1338 | overflow: hidden;
1339 | margin: -16px;
1340 | -webkit-flex-direction: row;
1341 | -ms-flex-direction: row;
1342 | flex-direction: row;
1343 | -webkit-flex-wrap: wrap;
1344 | -ms-flex-wrap: wrap;
1345 | flex-wrap: wrap;
1346 | -webkit-align-items: center;
1347 | -webkit-box-align: center;
1348 | -ms-flex-align: center;
1349 | align-items: center;
1350 | -webkit-box-pack: start;
1351 | -webkit-justify-content: flex-start;
1352 | -ms-flex-pack: start;
1353 | justify-content: flex-start;
1354 | }
1355 |
1356 | .emotion-0 {
1357 | box-sizing: border-box;
1358 | margin: 0;
1359 | min-width: 0;
1360 | position: relative;
1361 | margin-top: 16px;
1362 | margin-right: 16px;
1363 | margin-bottom: 16px;
1364 | margin-left: 16px;
1365 | -webkit-flex: 0 0 auto;
1366 | -ms-flex: 0 0 auto;
1367 | flex: 0 0 auto;
1368 | }
1369 |
1370 |
1373 |
1376 | Item 1
1377 |
1378 |
1381 | Item 2
1382 |
1383 |
1386 | Item 3
1387 |
1388 |
1389 | `;
1390 |
1391 | exports[`Wrap renders with defined theme gap (emotion) 1`] = `
1392 | .emotion-3 {
1393 | box-sizing: border-box;
1394 | margin: 0;
1395 | min-width: 0;
1396 | display: -webkit-box;
1397 | display: -webkit-flex;
1398 | display: -ms-flexbox;
1399 | display: flex;
1400 | overflow: hidden;
1401 | margin: -16px;
1402 | -webkit-flex-direction: row;
1403 | -ms-flex-direction: row;
1404 | flex-direction: row;
1405 | -webkit-flex-wrap: wrap;
1406 | -ms-flex-wrap: wrap;
1407 | flex-wrap: wrap;
1408 | -webkit-align-items: center;
1409 | -webkit-box-align: center;
1410 | -ms-flex-align: center;
1411 | align-items: center;
1412 | -webkit-box-pack: start;
1413 | -webkit-justify-content: flex-start;
1414 | -ms-flex-pack: start;
1415 | justify-content: flex-start;
1416 | }
1417 |
1418 | .emotion-0 {
1419 | box-sizing: border-box;
1420 | margin: 0;
1421 | min-width: 0;
1422 | position: relative;
1423 | margin-top: 16px;
1424 | margin-right: 16px;
1425 | margin-bottom: 16px;
1426 | margin-left: 16px;
1427 | -webkit-flex: 0 0 auto;
1428 | -ms-flex: 0 0 auto;
1429 | flex: 0 0 auto;
1430 | }
1431 |
1432 |
1435 |
1438 | Item 1
1439 |
1440 |
1443 | Item 2
1444 |
1445 |
1448 | Item 3
1449 |
1450 |
1451 | `;
1452 |
1453 | exports[`Wrap renders with defined theme gap (theme-ui) 1`] = `
1454 | .emotion-3 {
1455 | box-sizing: border-box;
1456 | margin: 0;
1457 | min-width: 0;
1458 | display: -webkit-box;
1459 | display: -webkit-flex;
1460 | display: -ms-flexbox;
1461 | display: flex;
1462 | overflow: hidden;
1463 | margin: -16px;
1464 | -webkit-flex-direction: row;
1465 | -ms-flex-direction: row;
1466 | flex-direction: row;
1467 | -webkit-flex-wrap: wrap;
1468 | -ms-flex-wrap: wrap;
1469 | flex-wrap: wrap;
1470 | -webkit-align-items: center;
1471 | -webkit-box-align: center;
1472 | -ms-flex-align: center;
1473 | align-items: center;
1474 | -webkit-box-pack: start;
1475 | -webkit-justify-content: flex-start;
1476 | -ms-flex-pack: start;
1477 | justify-content: flex-start;
1478 | }
1479 |
1480 | .emotion-0 {
1481 | box-sizing: border-box;
1482 | margin: 0;
1483 | min-width: 0;
1484 | position: relative;
1485 | margin-top: 16px;
1486 | margin-right: 16px;
1487 | margin-bottom: 16px;
1488 | margin-left: 16px;
1489 | -webkit-flex: 0 0 auto;
1490 | -ms-flex: 0 0 auto;
1491 | flex: 0 0 auto;
1492 | }
1493 |
1494 |
1497 |
1500 | Item 1
1501 |
1502 |
1505 | Item 2
1506 |
1507 |
1510 | Item 3
1511 |
1512 |
1513 | `;
1514 |
--------------------------------------------------------------------------------
/packages/raam/test/index.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import renderer from "react-test-renderer";
3 | import { matchers } from "jest-emotion";
4 | import { Inline, Flex, Stack, Wrap } from "../src";
5 | import { ThemeProvider as EmotionProvider } from "emotion-theming";
6 | import { ThemeProvider as ThemeUIProvider } from "theme-ui";
7 |
8 | expect.extend(matchers);
9 |
10 | const theme = { space: [0, 4, 8, 16, 32, 64, 128, 256, 512] };
11 | const renderJSON = (el: React.ReactNode) => renderer.create(el).toJSON();
12 |
13 | const emotionProvider = (el: React.ReactNode) => (
14 | {el}
15 | );
16 |
17 | const themeUIProvider = (el: React.ReactNode) => (
18 | {el}
19 | );
20 |
21 | describe("Flex", () => {
22 | test("renders", () => {
23 | const json = renderJSON(
24 |
25 | Item 1
26 | Item 2
27 | Item 3
28 |
29 | );
30 | expect(json).toMatchSnapshot();
31 | });
32 |
33 | test("renders an array of children", () => {
34 | const json = renderJSON({["Item 1", "Item 2", "Item 3"]} );
35 | expect(json).toMatchSnapshot();
36 | });
37 |
38 | test("renders children as list-items", () => {
39 | const elements = ["ul", "ol"] as const;
40 | const lists = renderJSON(
41 | <>
42 | {elements.map((element: typeof elements[number]) => (
43 |
44 | Item 1
45 | Item 2
46 | Item 3
47 |
48 | ))}
49 | >
50 | );
51 |
52 | expect(lists).toMatchSnapshot();
53 | });
54 |
55 | test("renders children with span elements", () => {
56 | const elements = ["span", "p", "h1", "h2", "h3", "h4", "h5", "h6"] as const;
57 | const span = renderJSON(
58 | <>
59 | {elements.map((element: typeof elements[number]) => (
60 |
61 | Item 1
62 | Item 2
63 | Item 3
64 |
65 | ))}
66 | >
67 | );
68 |
69 | expect(span).toMatchSnapshot();
70 | });
71 |
72 | describe("style props", () => {
73 | test("renders with customised flexbox props", () => {
74 | const flex = renderJSON(
75 |
88 | Item 1
89 | Item 2
90 | Item 3
91 |
92 | );
93 |
94 | expect(flex).toMatchSnapshot();
95 | });
96 |
97 | test("renders with defined gap", () => {
98 | const flex = renderJSON(
99 |
100 | Item 1
101 | Item 2
102 | Item 3
103 |
104 | );
105 |
106 | expect(flex).toMatchSnapshot();
107 | });
108 |
109 | test("renders with defined theme gap (emotion)", () => {
110 | const flex = renderJSON(
111 | emotionProvider(
112 |
113 | Item 1
114 | Item 2
115 | Item 3
116 |
117 | )
118 | );
119 | expect(flex).toMatchSnapshot();
120 | });
121 |
122 | test("renders with defined theme gap (theme-ui)", () => {
123 | const flex = renderJSON(
124 | themeUIProvider(
125 |
126 | Item 1
127 | Item 2
128 | Item 3
129 |
130 | )
131 | );
132 |
133 | expect(flex).toMatchSnapshot();
134 | });
135 | });
136 | });
137 |
138 | describe("Inline", () => {
139 | test("renders", () => {
140 | const json = renderJSON(
141 | {["Item 1", "Item 2", "Item 3"]}
142 | );
143 | expect(json).toMatchSnapshot();
144 | });
145 |
146 | test("renders with defined theme gap (emotion)", () => {
147 | const json = renderJSON(
148 | emotionProvider({["Item 1", "Item 2", "Item 3"]} )
149 | );
150 | expect(json).toMatchSnapshot();
151 | });
152 |
153 | test("renders with defined theme gap (theme-ui)", () => {
154 | const json = renderJSON(
155 | themeUIProvider({["Item 1", "Item 2", "Item 3"]} )
156 | );
157 |
158 | expect(json).toMatchSnapshot();
159 | });
160 | });
161 |
162 | describe("Stack", () => {
163 | test("renders", () => {
164 | const json = renderJSON(
165 | {["Item 1", "Item 2", "Item 3"]}
166 | );
167 | expect(json).toMatchSnapshot();
168 | });
169 |
170 | test("renders with defined theme gap (emotion)", () => {
171 | const json = renderJSON(
172 | emotionProvider({["Item 1", "Item 2", "Item 3"]} )
173 | );
174 | expect(json).toMatchSnapshot();
175 | });
176 |
177 | test("renders with defined theme gap (theme-ui)", () => {
178 | const json = renderJSON(
179 | themeUIProvider({["Item 1", "Item 2", "Item 3"]} )
180 | );
181 |
182 | expect(json).toMatchSnapshot();
183 | });
184 | });
185 |
186 | describe("Wrap", () => {
187 | test("renders", () => {
188 | const json = renderJSON(
189 | {["Item 1", "Item 2", "Item 3"]}
190 | );
191 | expect(json).toMatchSnapshot();
192 | });
193 |
194 | test("renders with defined theme gap (emotion)", () => {
195 | const json = renderJSON(
196 | emotionProvider({["Item 1", "Item 2", "Item 3"]} )
197 | );
198 | expect(json).toMatchSnapshot();
199 | });
200 |
201 | test("renders with defined theme gap (theme-ui)", () => {
202 | const json = renderJSON(
203 | themeUIProvider({["Item 1", "Item 2", "Item 3"]} )
204 | );
205 |
206 | expect(json).toMatchSnapshot();
207 | });
208 | });
209 |
--------------------------------------------------------------------------------
/packages/raam/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": false,
8 | "forceConsistentCasingInFileNames": true,
9 | "noEmit": true,
10 | "esModuleInterop": true,
11 | "module": "esnext",
12 | "moduleResolution": "node",
13 | "resolveJsonModule": true,
14 | "isolatedModules": false,
15 | "jsx": "preserve"
16 | },
17 | "exclude": ["node_modules"],
18 | "include": ["./src/**/*.ts", "./src/**/*.tsx"]
19 | }
20 |
--------------------------------------------------------------------------------