Skip to content

Commit 770542e

Browse files
authored
feat: add ui-components package (#2321)
* feat: add NatAmountInput
1 parent f5768be commit 770542e

28 files changed

Lines changed: 3363 additions & 26 deletions

.github/workflows/test-all-packages.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,10 @@ jobs:
275275
run: cd packages/deploy-script-support && yarn test
276276
env:
277277
ESM_DISABLE_CACHE: true
278+
- name: yarn test (ui-components)
279+
run: cd packages/ui-components && yarn test
280+
env:
281+
ESM_DISABLE_CACHE: true
278282

279283
##############
280284
# Long-running tests are executed individually.

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,5 @@ bundle-*.js
6161
.idea/
6262

6363
/packages.png
64+
packages/ui-components/compiled
65+
packages/ui-components/dist

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@
4343
"packages/deployment",
4444
"packages/notifier",
4545
"packages/xsnap",
46-
"packages/deploy-script-support"
46+
"packages/deploy-script-support",
47+
"packages/ui-components"
4748
],
4849
"devDependencies": {
4950
"@typescript-eslint/parser": "^4.18.0",

packages/ui-components/.gitignore

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.js
7+
8+
# testing
9+
/coverage
10+
11+
# production
12+
/build
13+
14+
# misc
15+
.DS_Store
16+
.env.local
17+
.env.development.local
18+
.env.test.local
19+
.env.production.local
20+
21+
npm-debug.log*
22+
yarn-debug.log*
23+
yarn-error.log*
24+
.eslintcache

packages/ui-components/README.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# UI Components
2+
3+
Reusable UI Components for [Agoric](https://agoric.com) [Dapps](https://agoric.com/documentation/dapps/), built with [React](https://reactjs.org) and [MaterialUI](https://materialui.com).
4+
5+
## NatAmountInput
6+
7+
A [React](https://reactjs.org) [MaterialUI TextField
8+
Input](https://material-ui.com/api/text-field/) which allows the user
9+
to enter a `Nat`. Handles `decimalPlaces` appropriately. This is a
10+
controlled component.
11+
12+
Example:
13+
14+
```
15+
import { NatAmountInput } from '@agoric/ui-components';
16+
17+
<NatAmountInput
18+
label={label} // the label
19+
value={amount && amount.value} // The value to display. Must be a Nat
20+
decimalPlaces={purse.displayInfo && purse.displayInfo.decimalPlaces}
21+
placesToShow={2}
22+
disabled={disabled} // disable the input
23+
error={amountError} // any error to display
24+
onChange={onAmountChange} // a callback called on user input changing the value
25+
onError={() => {}} // a callback called on errors
26+
/>
27+
```
28+
29+
## Yarn Test
30+
31+
```sh
32+
yarn build
33+
yarn test
34+
```
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"presets": ["@babel/preset-react"]
3+
}

packages/ui-components/exported.js

Whitespace-only changes.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// This file can contain .js-specific Typescript compiler config.
2+
{
3+
"compilerOptions": {
4+
"target": "esnext",
5+
6+
"noEmit": true,
7+
/*
8+
// The following flags are for creating .d.ts files:
9+
"noEmit": false,
10+
"declaration": true,
11+
"emitDeclarationOnly": true,
12+
*/
13+
"downlevelIteration": true,
14+
"strictNullChecks": true,
15+
"moduleResolution": "node",
16+
"jsx": "react",
17+
},
18+
"include": ["src/**/*.js", "test/**/*.js", "exported.js"],
19+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
{
2+
"name": "@agoric/ui-components",
3+
"version": "0.0.1",
4+
"description": "Reusable UI Components for Agoric Dapps, built with React and MaterialUI",
5+
"main": "src/index.js",
6+
"peerDependencies": {
7+
"@agoric/assert": "^0.2.3",
8+
"@agoric/ertp": "^0.10.0",
9+
"@agoric/eventual-send": "^0.13.3",
10+
"@agoric/install-ses": "^0.5.3",
11+
"@material-ui/core": "^4.11.3",
12+
"react": "^16.14.0",
13+
"react-dom": "^16.8.0"
14+
},
15+
"scripts": {
16+
"test": "BABEL_ENV='test' ava",
17+
"build:tests": "rm -rf compiled && BABEL_ENV='test' ./node_modules/.bin/babel test/components --out-dir compiled/test/components",
18+
"build:src": "rm -rf dist && BABEL_ENV='test' ./node_modules/.bin/babel src --out-dir dist",
19+
"build": "yarn build:src && yarn build:tests",
20+
"lint-fix": "yarn lint --fix",
21+
"lint": "yarn lint:types && yarn lint:eslint",
22+
"lint-check": "yarn lint",
23+
"lint:eslint": "eslint '**/*.js'",
24+
"lint:types": "tsc -p jsconfig.json"
25+
},
26+
"eslintConfig": {
27+
"extends": [
28+
"react-app",
29+
"@agoric"
30+
],
31+
"rules": {
32+
"no-use-before-define": "off",
33+
"@typescript-eslint/no-use-before-define": [
34+
"error"
35+
]
36+
}
37+
},
38+
"eslintIgnore": [
39+
"dist",
40+
"compiled"
41+
],
42+
"prettier": {
43+
"trailingComma": "all",
44+
"singleQuote": true
45+
},
46+
"devDependencies": {
47+
"@babel/cli": "^7.12.13",
48+
"@babel/core": "^7.12.13",
49+
"@babel/plugin-syntax-jsx": "^7.12.1",
50+
"@material-ui/core": "4.11.3",
51+
"@typescript-eslint/eslint-plugin": "^4.14.2",
52+
"ava": "^3.15.0",
53+
"babel-eslint": "^10.1.0",
54+
"babel-plugin-named-asset-import": "^0.3.7",
55+
"babel-preset-react-app": "^10.0.0",
56+
"enzyme": "^3.11.0",
57+
"enzyme-adapter-react-16": "^1.15.6",
58+
"eslint-config-react-app": "^6.0.0",
59+
"eslint-plugin-flowtype": "^5.2.0",
60+
"eslint-plugin-react": "^7.22.0",
61+
"eslint-plugin-react-hooks": "^4.2.0",
62+
"esm": "^3.2.25",
63+
"prettier": "^1.19.0",
64+
"react": "^16.14.0",
65+
"react-dom": "^16.8.0",
66+
"typescript": "^4.2.3"
67+
},
68+
"ava": {
69+
"files": [
70+
"compiled/test/components/**/test-*.js",
71+
"test/**/*.js",
72+
"!test/components"
73+
],
74+
"require": [
75+
"esm",
76+
"./test/_setup-enzyme-adapter.js"
77+
]
78+
},
79+
"publishConfig": {
80+
"access": "public"
81+
},
82+
"repository": {
83+
"type": "git",
84+
"url": "git+https://github.com/Agoric/agoric-sdk.git"
85+
},
86+
"keywords": [
87+
"smart",
88+
"contract",
89+
"cryptocurrency",
90+
"exchange",
91+
"tokens"
92+
],
93+
"author": "Agoric",
94+
"license": "Apache-2.0",
95+
"bugs": {
96+
"url": "https://github.com/Agoric/agoric-sdk/issues"
97+
},
98+
"homepage": "https://github.com/Agoric/agoric-sdk#readme",
99+
"files": [
100+
"src",
101+
"dist",
102+
"NEWS.md",
103+
"exported.js"
104+
],
105+
"dependencies": {
106+
"@agoric/nat": "^4.0.0"
107+
}
108+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import React from 'react';
2+
import { TextField } from '@material-ui/core';
3+
4+
import { parseAsNat } from '../display/natValue/parseAsNat';
5+
import { stringifyNat } from '../display/natValue/stringifyNat';
6+
7+
// https://material-ui.com/api/text-field/
8+
9+
const NatAmountInput = ({
10+
label,
11+
value,
12+
decimalPlaces = 0,
13+
placesToShow = 2,
14+
disabled,
15+
error,
16+
onChange,
17+
}) => {
18+
// No negative values allowed in the input
19+
const noNegativeValues = {
20+
inputProps: { min: 0 },
21+
};
22+
23+
const preventSubtractChar = e => {
24+
if (e.key === 'Subtract') {
25+
e.preventDefault();
26+
e.stopPropagation();
27+
}
28+
};
29+
30+
return (
31+
<TextField
32+
label={label}
33+
type="number"
34+
variant="outlined"
35+
fullWidth
36+
InputProps={noNegativeValues}
37+
onChange={ev => onChange(parseAsNat(ev.target.value, decimalPlaces))}
38+
onKeyPress={preventSubtractChar}
39+
value={stringifyNat(value, decimalPlaces, placesToShow)}
40+
disabled={disabled}
41+
error={error}
42+
/>
43+
);
44+
};
45+
46+
export default NatAmountInput;

0 commit comments

Comments
 (0)