Преглед на файлове

Add Next.js + MDX support

Implement Next.js MDX

Separate the docs from the code and tests.
tags/0.3.0
TheoryOfNekomata преди 4 години
родител
ревизия
36954ed21c
променени са 59 файла, в които са добавени 7524 реда и са изтрити 265 реда
  1. +2
    -2
      jest.config.js
  2. +0
    -25
      lib/components/Checkbox/Checkbox.mdx
  3. +0
    -20
      lib/components/Icon/Icon.mdx
  4. +0
    -32
      lib/components/RadioButton/RadioButton.mdx
  5. +0
    -45
      lib/components/Select/Select.mdx
  6. +0
    -71
      lib/components/TextInput/TextInput.mdx
  7. +0
    -42
      lib/services/isEmpty.test.ts
  8. +30
    -0
      packages/react-common-docs/README.md
  9. +9
    -0
      packages/react-common-docs/brand.tsx
  10. +2
    -0
      packages/react-common-docs/next-env.d.ts
  11. +6
    -0
      packages/react-common-docs/next.config.js
  12. +19
    -0
      packages/react-common-docs/package.json
  13. Двоични данни
      packages/react-common-docs/public/favicon.ico
  14. +52
    -0
      packages/react-common-docs/public/global.css
  15. +127
    -0
      packages/react-common-docs/public/theme/dark.css
  16. +138
    -0
      packages/react-common-docs/public/theme/light.css
  17. +4
    -0
      packages/react-common-docs/public/vercel.svg
  18. +91
    -0
      packages/react-common-docs/src/components/Nav.tsx
  19. +47
    -0
      packages/react-common-docs/src/components/Playground.tsx
  20. +96
    -0
      packages/react-common-docs/src/components/Sidebar.tsx
  21. +35
    -0
      packages/react-common-docs/src/pages/_app.tsx
  22. +45
    -0
      packages/react-common-docs/src/pages/_document.tsx
  23. +12
    -9
      packages/react-common-docs/src/pages/components/Button.mdx
  24. +26
    -0
      packages/react-common-docs/src/pages/components/Checkbox.mdx
  25. +21
    -0
      packages/react-common-docs/src/pages/components/Icon.mdx
  26. +33
    -0
      packages/react-common-docs/src/pages/components/RadioButton.mdx
  27. +46
    -0
      packages/react-common-docs/src/pages/components/Select.mdx
  28. +9
    -8
      packages/react-common-docs/src/pages/components/Slider.mdx
  29. +78
    -0
      packages/react-common-docs/src/pages/components/TextInput.mdx
  30. +1
    -0
      packages/react-common-docs/src/pages/index.md
  31. +0
    -0
      packages/react-common-docs/src/pages/theming.md
  32. +18
    -0
      packages/react-common-docs/src/sidebar.json
  33. +37
    -0
      packages/react-common-docs/tsconfig.json
  34. +6489
    -0
      packages/react-common-docs/yarn.lock
  35. +1
    -1
      packages/react-common/components/Button/Button.test.tsx
  36. +0
    -0
      packages/react-common/components/Button/Button.tsx
  37. +1
    -1
      packages/react-common/components/Checkbox/Checkbox.test.tsx
  38. +0
    -0
      packages/react-common/components/Checkbox/Checkbox.tsx
  39. +1
    -1
      packages/react-common/components/Icon/Icon.test.tsx
  40. +0
    -0
      packages/react-common/components/Icon/Icon.tsx
  41. +1
    -1
      packages/react-common/components/RadioButton/RadioButton.test.tsx
  42. +0
    -0
      packages/react-common/components/RadioButton/RadioButton.tsx
  43. +1
    -1
      packages/react-common/components/Select/Select.test.tsx
  44. +0
    -0
      packages/react-common/components/Select/Select.tsx
  45. +1
    -1
      packages/react-common/components/Slider/Slider.test.tsx
  46. +0
    -0
      packages/react-common/components/Slider/Slider.tsx
  47. +1
    -1
      packages/react-common/components/TextInput/TextInput.test.tsx
  48. +0
    -0
      packages/react-common/components/TextInput/TextInput.tsx
  49. +1
    -1
      packages/react-common/index.test.ts
  50. +0
    -0
      packages/react-common/index.ts
  51. +40
    -0
      packages/react-common/services/isEmpty.test.ts
  52. +0
    -0
      packages/react-common/services/isEmpty.ts
  53. +0
    -0
      packages/react-common/services/splitValueAndUnit.test.ts
  54. +0
    -0
      packages/react-common/services/splitValueAndUnit.ts
  55. +1
    -1
      packages/react-common/services/stringify.test.ts
  56. +0
    -0
      packages/react-common/services/stringify.ts
  57. +0
    -0
      packages/react-common/services/utilities.ts
  58. +1
    -1
      plopfile.js
  59. +1
    -1
      rollup.config.js

+ 2
- 2
jest.config.js Целия файл

@@ -5,8 +5,8 @@ module.exports = {
'./jest.setup.ts',
],
collectCoverageFrom: [
'./lib/**/*.{ts,tsx}',
'!./lib/**/*.stories.{ts,tsx}'
'./packages/**/*.{ts,tsx}',
'!./packages/**/*.stories.{ts,tsx}'
],
preset: 'ts-jest',
testTimeout: 30000,


+ 0
- 25
lib/components/Checkbox/Checkbox.mdx Целия файл

@@ -1,25 +0,0 @@
---
name: Checkbox
route: /components/checkbox
menu: Components
---

import { Playground, Props, Link } from 'docz'
import Checkbox from './Checkbox'

# Checkbox

Component for values that have an on/off state.

<Playground>
<Checkbox label="Accept Terms" />
</Playground>

## Props

<Props of={Checkbox} />

## See Also

- <Link to="../select">Select</Link> for a similar component suitable for selecting more values.
- <Link to="../radiobutton">RadioButton</Link> for a similar component on selecting a single value among very few choices.

+ 0
- 20
lib/components/Icon/Icon.mdx Целия файл

@@ -1,20 +0,0 @@
---
name: Icon
route: /components/icon
menu: Components
---

import { Playground, Props } from 'docz'
import Icon from './Icon'

# Icon

Component for displaying graphics.

<Playground>
<Icon name="check" label="OK" size="1.5rem" weight={0.125} />
</Playground>

## Props

<Props of={Icon} />

+ 0
- 32
lib/components/RadioButton/RadioButton.mdx Целия файл

@@ -1,32 +0,0 @@
---
name: RadioButton
route: /components/radiobutton
menu: Components
---

import { Playground, Props, Link } from 'docz'
import RadioButton from './RadioButton'

# RadioButton

Component for values which are to be selected from a few list of options.

<Playground>
<div style={{ display: 'grid', gap: '1rem', }}>
<div>
<RadioButton name="flavor" label="Chocolate" />
</div>
<div>
<RadioButton name="flavor" label="Vanilla" />
</div>
</div>
</Playground>

## Props

<Props of={RadioButton} />

## See Also

- <Link to="../checkbox">Checkbox</Link> for a similar component on selecting values among very few choices.
- <Link to="../select">Select</Link> for a similar component suitable for selecting more values.

+ 0
- 45
lib/components/Select/Select.mdx Целия файл

@@ -1,45 +0,0 @@
---
name: Select
route: /components/select
menu: Components
---

import { Playground, Props, Link } from 'docz'
import Select from './Select'

# Select

Component for selecting values from a larger number of options.

<Playground>
<Select>
<optgroup
label="Fruits"
>
<option value="mango">Mango</option>
<option value="strawberry">Strawberry</option>
<option value="blueberry">Blueberry</option>
</optgroup>
<optgroup
label="Classic"
>
<option value="chocolate">Chocolate</option>
<option value="vanilla">Vanilla</option>
</optgroup>
</Select>
</Playground>

## Props

<Props of={Select} />

## Usage Notes

The component will behave as `block`, i.e. it takes the remaining of the horizontal space.
To use the component together with layouts, see [TextInput](./textinput) for examples. Both `Select` and
`TextInput` have similar strategies on usage with layouts.

## See Also

- <Link to="../checkbox">Checkbox</Link> for a similar component on selecting values among very few choices.
- <Link to="../radiobutton">RadioButton</Link> for a similar component on selecting a single value among very few choices.

+ 0
- 71
lib/components/TextInput/TextInput.mdx Целия файл

@@ -1,71 +0,0 @@
---
name: TextInput
route: /components/textinput
menu: Components
---

import { Playground, Props, Link } from 'docz'
import TextInput from './TextInput'

# TextInput

Component for inputting textual values.

<Playground>
<TextInput label="Username" placeholder="johndoe" hint="the name you use to log in" />
</Playground>

## Props

<Props of={TextInput} />

## Usage Notes

The component will behave as `block`, i.e. it takes the remaining of the horizontal space.
To use the component together with layouts, see the following examples.

### Inline

The components are surrounded by `inline-block` elements. These surrounding elements have specified widths, which could
act as guide to the user on how long the expected input values are.

<Playground>
<form>
I am <span style={{ display: 'inline-block', width: '16rem', }}><TextInput label="Full name" hint="given and family name" /></span> and I live in <span style={{ display: 'inline-block', width: '24rem', }}><TextInput label="Address" hint="city, state and country" /></span>.
</form>
</Playground>

### Grid

It is advisable to put surrounding elements instead of the `TextInput` components themselves as children of the
element specified as `grid`. This is to be able to add complementing content to the components, if for example there are
some content that is best displayed outside the component instead of putting in the `hint` prop.

<Playground>
<form
style={{ display: 'grid', gridTemplateColumns: '4fr 4fr 5fr', gap: '1rem', }}
>
<div style={{ gridColumnStart: 1, gridColumnEnd: 4, }}>
<TextInput label="Address line 1" hint="unit/house number, building" />
</div>
<div style={{ gridColumnStart: 1, gridColumnEnd: 4, }}>
<TextInput label="Address line 2" hint="street, area" />
</div>
<div>
<TextInput size="large" label="City/Town" />
</div>
<div>
<TextInput size="large" label="State/Province" />
</div>
<div>
<TextInput size="large" label="Country" hint="abbreviations are accepted" />
<small>
Consult the <a href="#">fees table</a> for shipping fee details.
</small>
</div>
</form>
</Playground>

## See Also

- <Link to="../select">Select</Link> for a graphically-similar component suitable for selecting more values.

+ 0
- 42
lib/services/isEmpty.test.ts Целия файл

@@ -1,42 +0,0 @@
import * as fc from 'fast-check'
import isEmpty from './isEmpty'

describe('lib/services/isEmpty', () => {
it('should exist', () => {
expect(isEmpty).toBeDefined()
})

it('should be a function', () => {
expect(isEmpty).toBeFunction()
})

it('should accept 1 argument', () => {
expect(isEmpty).toHaveLength(1)
})

it('should return a boolean value', () => {
fc.assert(
fc.property(fc.anything(), (v) => {
expect(typeof isEmpty(v)).toBe('boolean')
}),
)
})

describe('on arguments', () => {
it('should return `true` on an argument with value of `undefined`', () => {
expect(isEmpty(undefined)).toBe(true)
})

it('should return `true` on an argument with value of `null`', () => {
expect(isEmpty(null)).toBe(true)
})

it('should return `false` on an argument with value that is neither `undefined` nor `null`', () => {
fc.assert(
fc.property(fc.anything().filter((v) => typeof v !== 'undefined' && v !== null), (v) => {
expect(isEmpty(v)).toBe(false)
}),
)
})
})
})

+ 30
- 0
packages/react-common-docs/README.md Целия файл

@@ -0,0 +1,30 @@
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).

## Getting Started

First, run the development server:

```bash
npm run dev
# or
yarn dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.

## Learn More

To learn more about Next.js, take a look at the following resources:

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.

You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!

## Deploy on Vercel

The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/import?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.

Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.

+ 9
- 0
packages/react-common-docs/brand.tsx Целия файл

@@ -0,0 +1,9 @@
const Brand = () => (
<div>
<strong>
Tesseract
</strong>
</div>
)

export default Brand

+ 2
- 0
packages/react-common-docs/next-env.d.ts Целия файл

@@ -0,0 +1,2 @@
/// <reference types="next" />
/// <reference types="next/types/global" />

+ 6
- 0
packages/react-common-docs/next.config.js Целия файл

@@ -0,0 +1,6 @@
const withMDX = require('next-mdx-frontmatter')({
extension: /\.mdx?$/
})
module.exports = withMDX({
pageExtensions: ['js', 'jsx', 'ts', 'tsx', 'md', 'mdx']
})

+ 19
- 0
packages/react-common-docs/package.json Целия файл

@@ -0,0 +1,19 @@
{
"name": "react-common-docs",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
},
"dependencies": {
"@mdx-js/loader": "^1.6.19",
"@tesseract-design/react-common": "^0.2.1",
"next": "10.0.1",
"next-mdx-frontmatter": "^0.0.3",
"pascalcase": "^1.0.0",
"react-live": "^2.2.3",
"styled-components": "^5.2.1"
}
}

Двоични данни
packages/react-common-docs/public/favicon.ico Целия файл

Преди След

+ 52
- 0
packages/react-common-docs/public/global.css Целия файл

@@ -0,0 +1,52 @@
body {
margin: 0;
}

h1 {
font-size: 3em;
text-transform: lowercase;
}

h2 {
font-size: 2em;
text-transform: lowercase;
}

h3 {
font-size: 1.75em;
text-transform: lowercase;
}

h4 {
text-transform: lowercase;
}

h5 {
text-transform: lowercase;
}

h6 {
text-transform: lowercase;
}

p {
margin: 2em 0;
}

small {
font-size: 0.75em;
}

a:focus {
color: var(--color-active);
outline: 0;
}

::selection {
background-color: var(--color-active);
color: var(--color-fg);
}

:root {
caret-color: var(--color-active);
}

+ 127
- 0
packages/react-common-docs/public/theme/dark.css Целия файл

@@ -0,0 +1,127 @@
@font-face {
font-family: 'Encode Sans';
font-stretch: semi-expanded;
font-weight: 400;
src:
local('Encode Sans Semi Expanded'),
local('Encode Sans');
}

@font-face {
font-family: 'Encode Sans';
font-stretch: semi-expanded;
font-weight: 700;
src:
local('Encode Sans Semi Expanded Bold'),
local('Encode Sans Semi Expanded'),
local('Encode Sans');
}

@font-face {
font-family: 'Encode Sans';
font-stretch: condensed;
font-weight: 100;
src:
local('Encode Sans Condensed Thin'),
local('Encode Sans Condensed'),
local('Encode Sans');
}

@font-face {
font-family: 'Encode Sans';
font-stretch: condensed;
font-weight: 200;
src:
local('Encode Sans Condensed ExtraLight'),
local('Encode Sans Condensed Extra Light'),
local('Encode Sans Condensed'),
local('Encode Sans');
}

@font-face {
font-family: 'Encode Sans';
font-stretch: condensed;
font-weight: 300;
src:
local('Encode Sans Condensed Light'),
local('Encode Sans Condensed'),
local('Encode Sans');
}

:root {
--color-active: #f90;
--font-family-base: 'Encode Sans Semi Expanded', 'Encode Sans', system-ui;
--font-stretch-base: semi-expanded;
--font-weight-base: 400;
--line-height-base: 2;
--font-family-headings:'Encode Sans Condensed', 'Encode Sans', system-ui;
--font-stretch-headings: condensed;
--font-weight-headings: 100;
--line-height-headings: 1.5;
--font-family-monospace: 'mononoki';
--font-size-root: 16px;
--color-negative: #222;
--color-positive: #eee;
--color-accent: #C78AB3;
--opacity-light: 0.25;
--opacity-lighter: 0.5;
--opacity-lightest: 0.75;
}

:root {
--color-bg: var(--color-negative, white);
--color-fg: var(--color-positive, black);
background-color: var(--color-bg);
color: var(--color-fg);
font-size: var(--font-size-root);
font-family: var(--font-family-base), sans-serif;
font-stretch: var(--font-stretch-base, normal);
font-weight: var(--font-weight-base, 400);
line-height: var(--line-height-base, 2);
}

h1 {
font-family: var(--font-family-headings), sans-serif;
font-stretch: var(--font-stretch-headings, normal);
font-weight: var(--font-weight-headings, 400);
line-height: var(--line-height-headings, 1.5);
}

h2 {
font-family: var(--font-family-headings), sans-serif;
font-stretch: var(--font-stretch-headings, normal);
font-weight: var(--font-weight-headings, 400);
line-height: var(--line-height-headings, 1.5);
}

h3 {
font-family: var(--font-family-headings), sans-serif;
font-stretch: var(--font-stretch-headings, normal);
font-weight: var(--font-weight-headings, 400);
line-height: var(--line-height-headings, 1.5);
}

h4 {
font-family: var(--font-family-headings), sans-serif;
font-stretch: var(--font-stretch-headings, normal);
font-weight: var(--font-weight-headings, 400);
line-height: var(--line-height-headings, 1.5);
}

h5 {
font-family: var(--font-family-headings), sans-serif;
font-stretch: var(--font-stretch-headings, normal);
font-weight: var(--font-weight-headings, 400);
line-height: var(--line-height-headings, 1.5);
}

h6 {
font-family: var(--font-family-headings), sans-serif;
font-stretch: var(--font-stretch-headings, normal);
font-weight: var(--font-weight-headings, 400);
line-height: var(--line-height-headings, 1.5);
}

a {
color: var(--color-accent);
}

+ 138
- 0
packages/react-common-docs/public/theme/light.css Целия файл

@@ -0,0 +1,138 @@
@font-face {
font-family: 'Encode Sans';
font-stretch: semi-expanded;
font-weight: 400;
src:
local('Encode Sans Semi Expanded'),
local('Encode Sans');
}

@font-face {
font-family: 'Encode Sans';
font-stretch: semi-expanded;
font-weight: 700;
src:
local('Encode Sans Semi Expanded Bold'),
local('Encode Sans Semi Expanded'),
local('Encode Sans');
}

@font-face {
font-family: 'Encode Sans';
font-stretch: condensed;
font-weight: 100;
src:
local('Encode Sans Condensed Thin'),
local('Encode Sans Condensed'),
local('Encode Sans');
}

@font-face {
font-family: 'Encode Sans';
font-stretch: condensed;
font-weight: 200;
src:
local('Encode Sans Condensed ExtraLight'),
local('Encode Sans Condensed Extra Light'),
local('Encode Sans Condensed'),
local('Encode Sans');
}

@font-face {
font-family: 'Encode Sans';
font-stretch: condensed;
font-weight: 300;
src:
local('Encode Sans Condensed Light'),
local('Encode Sans Condensed'),
local('Encode Sans');
}

:root {
--color-negative: #eee;
--color-positive: #222;
--color-accent: #ba6a9c;
--color-active: #f90;
--font-family-base: 'Encode Sans Semi Expanded', 'Encode Sans', system-ui;
--font-stretch-base: semi-expanded;
--font-weight-base: 400;
--line-height-base: 2;
--font-family-headings:'Encode Sans Condensed', 'Encode Sans', system-ui;
--font-stretch-headings: condensed;
--font-weight-headings: 100;
--line-height-headings: 1.5;
--font-family-monospace: 'mononoki';
--font-size-root: 16px;
--opacity-light: 0.5;
--opacity-lighter: 0.75;
--opacity-lightest: 0.875;
}

/*@media (prefers-color-scheme: dark) {*/
/* :root {*/
/* --color-negative: #222;*/
/* --color-positive: #eee;*/
/* --color-accent: #C78AB3;*/
/* --opacity-light: 0.25;*/
/* --opacity-lighter: 0.5;*/
/* --opacity-lightest: 0.75;*/
/* }*/
/*}*/

:root {
--color-bg: var(--color-negative, white);
--color-fg: var(--color-positive, black);
background-color: var(--color-bg);
color: var(--color-fg);
font-size: var(--font-size-root);
font-family: var(--font-family-base), sans-serif;
font-stretch: var(--font-stretch-base, normal);
font-weight: var(--font-weight-base, 400);
line-height: var(--line-height-base, 2);
}

h1 {
font-family: var(--font-family-headings), sans-serif;
font-stretch: var(--font-stretch-headings, normal);
font-weight: var(--font-weight-headings, 400);
line-height: var(--line-height-headings, 1.5);
}

h2 {
font-family: var(--font-family-headings), sans-serif;
font-stretch: var(--font-stretch-headings, normal);
font-weight: var(--font-weight-headings, 400);
line-height: var(--line-height-headings, 1.5);
}

h3 {
font-family: var(--font-family-headings), sans-serif;
font-stretch: var(--font-stretch-headings, normal);
font-weight: var(--font-weight-headings, 400);
line-height: var(--line-height-headings, 1.5);
}

h4 {
font-family: var(--font-family-headings), sans-serif;
font-stretch: var(--font-stretch-headings, normal);
font-weight: var(--font-weight-headings, 400);
line-height: var(--line-height-headings, 1.5);
}

h5 {
font-family: var(--font-family-headings), sans-serif;
font-stretch: var(--font-stretch-headings, normal);
font-weight: var(--font-weight-headings, 400);
line-height: var(--line-height-headings, 1.5);
}

h6 {
font-family: var(--font-family-headings), sans-serif;
font-stretch: var(--font-stretch-headings, normal);
font-weight: var(--font-weight-headings, 400);
line-height: var(--line-height-headings, 1.5);
}

a {
color: var(--color-accent);
}

+ 4
- 0
packages/react-common-docs/public/vercel.svg Целия файл

@@ -0,0 +1,4 @@
<svg width="283" height="64" viewBox="0 0 283 64" fill="none"
xmlns="http://www.w3.org/2000/svg">
<path d="M141.04 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.46 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM248.72 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.45 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM200.24 34c0 6 3.92 10 10 10 4.12 0 7.21-1.87 8.8-4.92l7.68 4.43c-3.18 5.3-9.14 8.49-16.48 8.49-11.05 0-19-7.2-19-18s7.96-18 19-18c7.34 0 13.29 3.19 16.48 8.49l-7.68 4.43c-1.59-3.05-4.68-4.92-8.8-4.92-6.07 0-10 4-10 10zm82.48-29v46h-9V5h9zM36.95 0L73.9 64H0L36.95 0zm92.38 5l-27.71 48L73.91 5H84.3l17.32 30 17.32-30h10.39zm58.91 12v9.69c-1-.29-2.06-.49-3.2-.49-5.81 0-10 4-10 10V51h-9V17h9v9.2c0-5.08 5.91-9.2 13.2-9.2z" fill="#000"/>
</svg>

+ 91
- 0
packages/react-common-docs/src/components/Nav.tsx Целия файл

@@ -0,0 +1,91 @@
import * as React from 'react'
import Link from 'next/link'
import styled from 'styled-components'

const StyledLink = styled('a')({
display: 'block',
textDecoration: 'none',
})

const Container = styled('span')({
display: 'flex',
alignItems: 'center',
padding: '0 1rem',
height: '2rem',
margin: '0 0 0 auto',
'@media (min-width: 720px)': {
maxWidth: 360,
},
})

const HeaderContainer = styled(Container)({
marginTop: '2rem',
})

const NavContainer = styled('div')({

})

const Nav = ({
data,
}) => {
if (Array.isArray(data)) {
return (
<NavContainer>
{
data.map(d => (
<Nav
data={d}
/>
))
}
</NavContainer>
)
}
if (typeof data === 'object') {
const [entry] = Object.entries(data)
const [key, value] = entry
if (Array.isArray(value)) {
return (
<NavContainer>
<HeaderContainer>
{key}
</HeaderContainer>
{
value.map(v => (
<Nav
data={v}
/>
))
}
</NavContainer>
)
}
return (
<Link
href={value}
passHref
>
<StyledLink>
<Container>
{key}
</Container>
</StyledLink>
</Link>
)
}
return (
<Link
href={data}
passHref
>
<StyledLink>
<Container>
{data}
</Container>
</StyledLink>
</Link>
)
}

export default Nav

+ 47
- 0
packages/react-common-docs/src/components/Playground.tsx Целия файл

@@ -0,0 +1,47 @@
import * as React from 'react'
import {
LiveProvider,
LiveEditor,
LivePreview
} from 'react-live'
import styled from 'styled-components'

const Figure = styled('figure')({
margin: 0,
})

const Playground = ({
components,
code,
label,
}) => {
const indentLevel = code.indexOf('<') - 1
const normalizedCode = code
.split('\n')
.map((s: string) => s.slice(indentLevel))
.filter((s: string) => s.trim().length > 0)
.join('\n')

return (
<div>
<Figure>
{
label
&& (
<figcaption>
{label}
</figcaption>
)
}
<div>
<LiveProvider code={normalizedCode} scope={components}>
<LivePreview />
<LiveEditor />
</LiveProvider>
</div>
</Figure>
</div>
)
}

export default Playground

+ 96
- 0
packages/react-common-docs/src/components/Sidebar.tsx Целия файл

@@ -0,0 +1,96 @@
import styled from 'styled-components'
import Nav from './Nav'
import Link from 'next/link'
import * as React from 'react'
import { Checkbox } from '@tesseract-design/react-common'

const StyledLink = styled('a')({
display: 'block',
textDecoration: 'none',
marginBottom: '2rem',
})

const Container = styled('span')({
display: 'flex',
alignItems: 'center',
padding: '0 1rem',
height: '2rem',
margin: '0 0 0 auto',
'@media (min-width: 720px)': {
maxWidth: 360,
},
})

const Base = styled('aside')({
position: 'fixed',
top: 0,
left: '-100%',
width: '100%',
height: '100%',
backgroundColor: 'var(--color-bg)',
zIndex: 4,
'@media (min-width: 720px)': {
left: 0,
width: `${100 / 3}%`,
maxWidth: 'none',
height: '100%',
'+ *': {
paddingLeft: `${100 / 3}%`,
boxSizing: 'border-box',
},
},
})

const Sidebar = ({
data,
brand: Brand,
}) => {
const [dark, setDark] = React.useState(false)

const toggleDarkMode = b => () => {
setDark(b)
}

React.useEffect(() => {
const stylesheets = Array.from(window.document.querySelectorAll('link[title]'))

stylesheets.forEach(s => {
if (s.getAttribute('rel').includes('alternate')) {
s.setAttribute('rel', 'stylesheet')
s.removeAttribute('disabled')
} else {
s.setAttribute('rel', 'alternate stylesheet')
s.setAttribute('disabled', 'disabled')
}
})
}, [dark])

return (
<Base>
<Container>
<input
type="checkbox"
defaultChecked={dark}
onChange={toggleDarkMode(!dark)}
/>
</Container>
<nav>
<Link
href="/"
passHref
>
<StyledLink>
<Container>
<Brand />
</Container>
</StyledLink>
</Link>
<Nav
data={data.nav}
/>
</nav>
</Base>
)
}

export default Sidebar

+ 35
- 0
packages/react-common-docs/src/pages/_app.tsx Целия файл

@@ -0,0 +1,35 @@
import '../../public/global.css'
import '../../public/theme/dark.css'
import sidebar from '../sidebar.json'
import brand from '../../brand'
import Sidebar from '../components/Sidebar'
import styled from 'styled-components'

const Container = styled('div')({
maxWidth: 720,
margin: '0 auto',
padding: '0 1rem',
boxSizing: 'border-box',
})

const App = ({
Component,
pageProps,
...etc
}) => (
<div>
<Sidebar
brand={brand}
data={sidebar}
/>
<main>
<Container>
<Component
{...pageProps}
/>
</Container>
</main>
</div>
)

export default App

+ 45
- 0
packages/react-common-docs/src/pages/_document.tsx Целия файл

@@ -0,0 +1,45 @@
import Document, { Html, Head, Main, NextScript, DocumentContext } from 'next/document'
import { ServerStyleSheet } from 'styled-components'

export default class MyDocument extends Document {
static async getInitialProps(ctx: DocumentContext) {
const sheet = new ServerStyleSheet()
const originalRenderPage = ctx.renderPage

try {
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) =>
sheet.collectStyles(<App {...props} />),
})

const initialProps = await Document.getInitialProps(ctx)
return {
...initialProps,
styles: (
<>
{initialProps.styles}
<link rel="stylesheet" href="/global.css" />
<link rel="stylesheet" title="Dark" href="/theme/dark.css" />
<link rel="alternate stylesheet" title="Light" href="/theme/light.css" />
{sheet.getStyleElement()}
</>
),
}
} finally {
sheet.seal()
}
}

render() {
return (
<Html lang="en-PH">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}

lib/components/Button/Button.mdx → packages/react-common-docs/src/pages/components/Button.mdx Целия файл

@@ -1,23 +1,26 @@
---
name: Button
route: /components/button
menu: Components
title: Button
---

import { Playground, Props } from 'docz'
import Button from './Button'
import { Button } from '@tesseract-design/react-common'
import Playground from '../../components/Playground'

# Button

Component for performing an action upon activation (e.g. when clicked).

<Playground>
<Button>Perform Action</Button>
</Playground>
<Playground
code={`
<Button>
Perform Action
</Button>
`}
components={{ Button }}
/>

## Props

<Props of={Button} />
Props

## Usage Notes


+ 26
- 0
packages/react-common-docs/src/pages/components/Checkbox.mdx Целия файл

@@ -0,0 +1,26 @@
---
name: Checkbox
---

import { Checkbox } from '@tesseract-design/react-common'
import Playground from '../../components/Playground'

# Checkbox

Component for values that have an on/off state.

<Playground
components={{ Checkbox }}
code={`
<Checkbox label="Accept Terms" />
`}
/>

## Props

Props

## See Also

- [Select](./Select) for a similar component suitable for selecting more values.
- [RadioButton](./RadioButton) for a similar component on selecting a single value among very few choices.

+ 21
- 0
packages/react-common-docs/src/pages/components/Icon.mdx Целия файл

@@ -0,0 +1,21 @@
---
name: Icon
---

import { Icon } from '@tesseract-design/react-common'
import Playground from '../../components/Playground'

# Icon

Component for displaying graphics.

<Playground
components={{ Icon }}
code={`
<Icon name="check" label="OK" size="1.5rem" weight={0.125} />
`}
/>

## Props

Props

+ 33
- 0
packages/react-common-docs/src/pages/components/RadioButton.mdx Целия файл

@@ -0,0 +1,33 @@
---
name: RadioButton
---

import { RadioButton } from '@tesseract-design/react-common'
import Playground from '../../components/Playground'

# RadioButton

Component for values which are to be selected from a few list of options.

<Playground
components={{ RadioButton }}
code={`
<div style={{ display: 'grid', gap: '1rem', }}>
<div>
<RadioButton name="flavor" label="Chocolate" />
</div>
<div>
<RadioButton name="flavor" label="Vanilla" />
</div>
</div>
`}
/>

## Props

Props

## See Also

- [Checkbox](./Checkbox) for a similar component on selecting values among very few choices.
- [Select](./Select) for a similar component suitable for selecting more values.

+ 46
- 0
packages/react-common-docs/src/pages/components/Select.mdx Целия файл

@@ -0,0 +1,46 @@
---
name: Select
---

import { Select } from '@tesseract-design/react-common'
import Playground from '../../components/Playground'

# Select

Component for selecting values from a larger number of options.

<Playground
components={{ Select }}
code={`
<Select>
<optgroup
label="Fruits"
>
<option value="mango">Mango</option>
<option value="strawberry">Strawberry</option>
<option value="blueberry">Blueberry</option>
</optgroup>
<optgroup
label="Classic"
>
<option value="chocolate">Chocolate</option>
<option value="vanilla">Vanilla</option>
</optgroup>
</Select>
`}
/>

## Props

Props

## Usage Notes

The component will behave as `block`, i.e. it takes the remaining of the horizontal space.
To use the component together with layouts, see [TextInput](./TextInput) for examples. Both `Select` and
`TextInput` have similar strategies on usage with layouts.

## See Also

- [Checkbox](./Checkbox) for a similar component on selecting values among very few choices.
- [RadioButton](./RadioButton) for a similar component on selecting a single value among very few choices.

lib/components/Slider/Slider.mdx → packages/react-common-docs/src/pages/components/Slider.mdx Целия файл

@@ -1,11 +1,9 @@
---
name: Slider
route: /components/slider
menu: Components
---

import { Playground, Props } from 'docz'
import Slider from './Slider'
import { Slider } from '@tesseract-design/react-common'
import Playground from '../../components/Playground'

# Slider

@@ -14,13 +12,16 @@ Component for inputting numeric values in a graphical manner.
The component is styled using client-side scripts. When the component is rendered server-side,
the component falls back into the original `<input type="range">` element.

<Playground>
<Slider />
</Playground>
<Playground
components={{ Slider }}
code={`
<Slider />
`}
/>

## Props

<Props of={Slider} />
Props

## See Also


+ 78
- 0
packages/react-common-docs/src/pages/components/TextInput.mdx Целия файл

@@ -0,0 +1,78 @@
---
name: TextInput
---

import { TextInput } from '@tesseract-design/react-common'
import Playground from '../../components/Playground'

# TextInput

Component for inputting textual values.

<Playground
components={{ TextInput }}
code={`
<TextInput label="Username" placeholder="johndoe" hint="the name you use to log in" />
`}
/>

## Props

Props

## Usage Notes

The component will behave as `block`, i.e. it takes the remaining of the horizontal space.
To use the component together with layouts, see the following examples.

### Inline

The components are surrounded by `inline-block` elements. These surrounding elements have specified widths, which could
act as guide to the user on how long the expected input values are.

<Playground
components={{ TextInput }}
code={`
<form>
I am <span style={{ display: 'inline-block', width: '16rem', }}><TextInput label="Full name" hint="given and family name" /></span> and I live in <span style={{ display: 'inline-block', width: '24rem', }}><TextInput label="Address" hint="city, state and country" /></span>.
</form>
`}
/>

### Grid

It is advisable to put surrounding elements instead of the `TextInput` components themselves as children of the
element specified as `grid`. This is to be able to add complementing content to the components, if for example there are
some content that is best displayed outside the component instead of putting in the `hint` prop.

<Playground
components={{ TextInput }}
code={`
<form
style={{ display: 'grid', gridTemplateColumns: '4fr 4fr 5fr', gap: '1rem', }}
>
<div style={{ gridColumnStart: 1, gridColumnEnd: 4, }}>
<TextInput label="Address line 1" hint="unit/house number, building" />
</div>
<div style={{ gridColumnStart: 1, gridColumnEnd: 4, }}>
<TextInput label="Address line 2" hint="street, area" />
</div>
<div>
<TextInput size="large" label="City/Town" />
</div>
<div>
<TextInput size="large" label="State/Province" />
</div>
<div>
<TextInput size="large" label="Country" hint="abbreviations are accepted" />
<small>
Consult the <a href="#">fees table</a> for shipping fee details.
</small>
</div>
</form>
`}
/>

## See Also

- [Select](./Select) for a graphically-similar component suitable for selecting more values.

+ 1
- 0
packages/react-common-docs/src/pages/index.md Целия файл

@@ -0,0 +1 @@
../../../../README.md

docs/theming.md → packages/react-common-docs/src/pages/theming.md Целия файл


+ 18
- 0
packages/react-common-docs/src/sidebar.json Целия файл

@@ -0,0 +1,18 @@
{
"nav": [
{
"Theming": "/theming"
},
{
"Components": [
{ "Button": "/components/Button" },
{ "Checkbox": "/components/Checkbox" },
{ "Icon": "/components/Icon" },
{ "RadioButton": "/components/RadioButton" },
{ "Select": "/components/Select" },
{ "Slider": "/components/Slider" },
{ "TextInput": "/components/TextInput" }
]
}
]
}

+ 37
- 0
packages/react-common-docs/tsconfig.json Целия файл

@@ -0,0 +1,37 @@
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "preserve",
"declaration": true,
"declarationDir": "./dist",
"sourceMap": true
},
"exclude": [
"node_modules",
"**/*.test.ts",
"**/*.test.tsx",
"utilities/**/*",
"jest.setup.ts"
],
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx"
]
}

+ 6489
- 0
packages/react-common-docs/yarn.lock
Файловите разлики са ограничени, защото са твърде много
Целия файл


lib/components/Button/Button.test.tsx → packages/react-common/components/Button/Button.test.tsx Целия файл

@@ -1,5 +1,5 @@
/// <reference types="jest-enzyme" />
/// <reference path="../../../utilities/jest/extensions.ts" />
/// <reference path="../../../../utilities/jest/extensions.ts" />

import * as fc from 'fast-check'
import * as Enzyme from 'enzyme'

lib/components/Button/Button.tsx → packages/react-common/components/Button/Button.tsx Целия файл


lib/components/Checkbox/Checkbox.test.tsx → packages/react-common/components/Checkbox/Checkbox.test.tsx Целия файл

@@ -1,5 +1,5 @@
/// <reference types="jest-enzyme" />
/// <reference path="../../../utilities/jest/extensions.ts" />
/// <reference path="../../../../utilities/jest/extensions.ts" />

import * as fc from 'fast-check'
import * as Enzyme from 'enzyme'

lib/components/Checkbox/Checkbox.tsx → packages/react-common/components/Checkbox/Checkbox.tsx Целия файл


lib/components/Icon/Icon.test.tsx → packages/react-common/components/Icon/Icon.test.tsx Целия файл

@@ -1,5 +1,5 @@
/// <reference types="jest-enzyme" />
/// <reference path="../../../utilities/jest/extensions.ts" />
/// <reference path="../../../../utilities/jest/extensions.ts" />

import * as fc from 'fast-check'
import * as Enzyme from 'enzyme'

lib/components/Icon/Icon.tsx → packages/react-common/components/Icon/Icon.tsx Целия файл


lib/components/RadioButton/RadioButton.test.tsx → packages/react-common/components/RadioButton/RadioButton.test.tsx Целия файл

@@ -1,5 +1,5 @@
/// <reference types="jest-enzyme" />
/// <reference path="../../../utilities/jest/extensions.ts" />
/// <reference path="../../../../utilities/jest/extensions.ts" />

import * as fc from 'fast-check'
import * as Enzyme from 'enzyme'

lib/components/RadioButton/RadioButton.tsx → packages/react-common/components/RadioButton/RadioButton.tsx Целия файл


lib/components/Select/Select.test.tsx → packages/react-common/components/Select/Select.test.tsx Целия файл

@@ -1,5 +1,5 @@
/// <reference types="jest-enzyme" />
/// <reference path="../../../utilities/jest/extensions.ts" />
/// <reference path="../../../../utilities/jest/extensions.ts" />

import * as fc from 'fast-check'
import * as Enzyme from 'enzyme'

lib/components/Select/Select.tsx → packages/react-common/components/Select/Select.tsx Целия файл


lib/components/Slider/Slider.test.tsx → packages/react-common/components/Slider/Slider.test.tsx Целия файл

@@ -1,5 +1,5 @@
/// <reference types="jest-enzyme" />
/// <reference path="../../../utilities/jest/extensions.ts" />
/// <reference path="../../../../utilities/jest/extensions.ts" />

import * as fc from 'fast-check'
import * as Enzyme from 'enzyme'

lib/components/Slider/Slider.tsx → packages/react-common/components/Slider/Slider.tsx Целия файл


lib/components/TextInput/TextInput.test.tsx → packages/react-common/components/TextInput/TextInput.test.tsx Целия файл

@@ -1,5 +1,5 @@
/// <reference types="jest-enzyme" />
/// <reference path="../../../utilities/jest/extensions.ts" />
/// <reference path="../../../../utilities/jest/extensions.ts" />

import * as fc from 'fast-check'
import * as Enzyme from 'enzyme'

lib/components/TextInput/TextInput.tsx → packages/react-common/components/TextInput/TextInput.tsx Целия файл


lib/index.test.ts → packages/react-common/index.test.ts Целия файл

@@ -1,5 +1,5 @@
/// <reference types="jest-enzyme" />
/// <reference path="../utilities/jest/extensions.ts" />
/// <reference path="../../utilities/jest/extensions.ts" />

import * as T from './index'


lib/index.ts → packages/react-common/index.ts Целия файл


+ 40
- 0
packages/react-common/services/isEmpty.test.ts Целия файл

@@ -0,0 +1,40 @@
import * as fc from 'fast-check'
import isEmpty from './isEmpty'

it('should exist', () => {
expect(isEmpty).toBeDefined()
})

it('should be a function', () => {
expect(typeof isEmpty).toBe('function')
})

it('should accept 1 argument', () => {
expect(isEmpty).toHaveLength(1)
})

it('should return a boolean value', () => {
fc.assert(
fc.property(fc.anything(), (v) => {
expect(typeof isEmpty(v)).toBe('boolean')
}),
)
})

describe('on arguments', () => {
it('should return `true` on an argument with value of `undefined`', () => {
expect(isEmpty(undefined)).toBe(true)
})

it('should return `true` on an argument with value of `null`', () => {
expect(isEmpty(null)).toBe(true)
})

it('should return `false` on an argument with value that is neither `undefined` nor `null`', () => {
fc.assert(
fc.property(fc.anything().filter((v) => typeof v !== 'undefined' && v !== null), (v) => {
expect(isEmpty(v)).toBe(false)
}),
)
})
})

lib/services/isEmpty.ts → packages/react-common/services/isEmpty.ts Целия файл


lib/services/splitValueAndUnit.test.ts → packages/react-common/services/splitValueAndUnit.test.ts Целия файл


lib/services/splitValueAndUnit.ts → packages/react-common/services/splitValueAndUnit.ts Целия файл


lib/services/stringify.test.ts → packages/react-common/services/stringify.test.ts Целия файл

@@ -1,5 +1,5 @@
import * as fc from 'fast-check'
import * as fcArb from '../../utilities/fast-check/arbitraries'
import * as fcArb from '../../../utilities/fast-check/arbitraries'
import stringify from './stringify'

it('should exist', () => {

lib/services/stringify.ts → packages/react-common/services/stringify.ts Целия файл


lib/services/utilities.ts → packages/react-common/services/utilities.ts Целия файл


+ 1
- 1
plopfile.js Целия файл

@@ -23,7 +23,7 @@ module.exports = plop => {
type: 'addMany',
templateFiles: 'plop/templates/component/*',
base: 'plop/templates/component',
destination: 'lib/components/{{pascalCase name}}',
destination: 'packages/react-common/components/{{pascalCase name}}',
},
],
})


+ 1
- 1
rollup.config.js Целия файл

@@ -4,7 +4,7 @@ import typescript from '@rollup/plugin-typescript'

import pkg from './package.json'

const ENTRY_POINT = './lib/index.ts'
const ENTRY_POINT = './packages/react-common/index.ts'

export default {
input: ENTRY_POINT,


Зареждане…
Отказ
Запис