-
Notifications
You must be signed in to change notification settings - Fork 207
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add ui-components package (#2321)
* feat: add NatAmountInput
- Loading branch information
1 parent
f5768be
commit 770542e
Showing
28 changed files
with
3,363 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -61,3 +61,5 @@ bundle-*.js | |
.idea/ | ||
|
||
/packages.png | ||
packages/ui-components/compiled | ||
packages/ui-components/dist |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
/.pnp | ||
.pnp.js | ||
|
||
# testing | ||
/coverage | ||
|
||
# production | ||
/build | ||
|
||
# misc | ||
.DS_Store | ||
.env.local | ||
.env.development.local | ||
.env.test.local | ||
.env.production.local | ||
|
||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
.eslintcache |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# UI Components | ||
|
||
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). | ||
|
||
## NatAmountInput | ||
|
||
A [React](https://reactjs.org) [MaterialUI TextField | ||
Input](https://material-ui.com/api/text-field/) which allows the user | ||
to enter a `Nat`. Handles `decimalPlaces` appropriately. This is a | ||
controlled component. | ||
|
||
Example: | ||
|
||
``` | ||
import { NatAmountInput } from '@agoric/ui-components'; | ||
<NatAmountInput | ||
label={label} // the label | ||
value={amount && amount.value} // The value to display. Must be a Nat | ||
decimalPlaces={purse.displayInfo && purse.displayInfo.decimalPlaces} | ||
placesToShow={2} | ||
disabled={disabled} // disable the input | ||
error={amountError} // any error to display | ||
onChange={onAmountChange} // a callback called on user input changing the value | ||
onError={() => {}} // a callback called on errors | ||
/> | ||
``` | ||
|
||
## Yarn Test | ||
|
||
```sh | ||
yarn build | ||
yarn test | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"presets": ["@babel/preset-react"] | ||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// This file can contain .js-specific Typescript compiler config. | ||
{ | ||
"compilerOptions": { | ||
"target": "esnext", | ||
|
||
"noEmit": true, | ||
/* | ||
// The following flags are for creating .d.ts files: | ||
"noEmit": false, | ||
"declaration": true, | ||
"emitDeclarationOnly": true, | ||
*/ | ||
"downlevelIteration": true, | ||
"strictNullChecks": true, | ||
"moduleResolution": "node", | ||
"jsx": "react", | ||
}, | ||
"include": ["src/**/*.js", "test/**/*.js", "exported.js"], | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
{ | ||
"name": "@agoric/ui-components", | ||
"version": "0.0.1", | ||
"description": "Reusable UI Components for Agoric Dapps, built with React and MaterialUI", | ||
"main": "src/index.js", | ||
"peerDependencies": { | ||
"@agoric/assert": "^0.2.3", | ||
"@agoric/ertp": "^0.10.0", | ||
"@agoric/eventual-send": "^0.13.3", | ||
"@agoric/install-ses": "^0.5.3", | ||
"@material-ui/core": "^4.11.3", | ||
"react": "^16.14.0", | ||
"react-dom": "^16.8.0" | ||
}, | ||
"scripts": { | ||
"test": "BABEL_ENV='test' ava", | ||
"build:tests": "rm -rf compiled && BABEL_ENV='test' ./node_modules/.bin/babel test/components --out-dir compiled/test/components", | ||
"build:src": "rm -rf dist && BABEL_ENV='test' ./node_modules/.bin/babel src --out-dir dist", | ||
"build": "yarn build:src && yarn build:tests", | ||
"lint-fix": "yarn lint --fix", | ||
"lint": "yarn lint:types && yarn lint:eslint", | ||
"lint-check": "yarn lint", | ||
"lint:eslint": "eslint '**/*.js'", | ||
"lint:types": "tsc -p jsconfig.json" | ||
}, | ||
"eslintConfig": { | ||
"extends": [ | ||
"react-app", | ||
"@agoric" | ||
], | ||
"rules": { | ||
"no-use-before-define": "off", | ||
"@typescript-eslint/no-use-before-define": [ | ||
"error" | ||
] | ||
} | ||
}, | ||
"eslintIgnore": [ | ||
"dist", | ||
"compiled" | ||
], | ||
"prettier": { | ||
"trailingComma": "all", | ||
"singleQuote": true | ||
}, | ||
"devDependencies": { | ||
"@babel/cli": "^7.12.13", | ||
"@babel/core": "^7.12.13", | ||
"@babel/plugin-syntax-jsx": "^7.12.1", | ||
"@material-ui/core": "4.11.3", | ||
"@typescript-eslint/eslint-plugin": "^4.14.2", | ||
"ava": "^3.15.0", | ||
"babel-eslint": "^10.1.0", | ||
"babel-plugin-named-asset-import": "^0.3.7", | ||
"babel-preset-react-app": "^10.0.0", | ||
"enzyme": "^3.11.0", | ||
"enzyme-adapter-react-16": "^1.15.6", | ||
"eslint-config-react-app": "^6.0.0", | ||
"eslint-plugin-flowtype": "^5.2.0", | ||
"eslint-plugin-react": "^7.22.0", | ||
"eslint-plugin-react-hooks": "^4.2.0", | ||
"esm": "^3.2.25", | ||
"prettier": "^1.19.0", | ||
"react": "^16.14.0", | ||
"react-dom": "^16.8.0", | ||
"typescript": "^4.2.3" | ||
}, | ||
"ava": { | ||
"files": [ | ||
"compiled/test/components/**/test-*.js", | ||
"test/**/*.js", | ||
"!test/components" | ||
], | ||
"require": [ | ||
"esm", | ||
"./test/_setup-enzyme-adapter.js" | ||
] | ||
}, | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/Agoric/agoric-sdk.git" | ||
}, | ||
"keywords": [ | ||
"smart", | ||
"contract", | ||
"cryptocurrency", | ||
"exchange", | ||
"tokens" | ||
], | ||
"author": "Agoric", | ||
"license": "Apache-2.0", | ||
"bugs": { | ||
"url": "https://github.com/Agoric/agoric-sdk/issues" | ||
}, | ||
"homepage": "https://github.com/Agoric/agoric-sdk#readme", | ||
"files": [ | ||
"src", | ||
"dist", | ||
"NEWS.md", | ||
"exported.js" | ||
], | ||
"dependencies": { | ||
"@agoric/nat": "^4.0.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import React from 'react'; | ||
import { TextField } from '@material-ui/core'; | ||
|
||
import { parseAsNat } from '../display/natValue/parseAsNat'; | ||
import { stringifyNat } from '../display/natValue/stringifyNat'; | ||
|
||
// https://material-ui.com/api/text-field/ | ||
|
||
const NatAmountInput = ({ | ||
label, | ||
value, | ||
decimalPlaces = 0, | ||
placesToShow = 2, | ||
disabled, | ||
error, | ||
onChange, | ||
}) => { | ||
// No negative values allowed in the input | ||
const noNegativeValues = { | ||
inputProps: { min: 0 }, | ||
}; | ||
|
||
const preventSubtractChar = e => { | ||
if (e.key === 'Subtract') { | ||
e.preventDefault(); | ||
e.stopPropagation(); | ||
} | ||
}; | ||
|
||
return ( | ||
<TextField | ||
label={label} | ||
type="number" | ||
variant="outlined" | ||
fullWidth | ||
InputProps={noNegativeValues} | ||
onChange={ev => onChange(parseAsNat(ev.target.value, decimalPlaces))} | ||
onKeyPress={preventSubtractChar} | ||
value={stringifyNat(value, decimalPlaces, placesToShow)} | ||
disabled={disabled} | ||
error={error} | ||
/> | ||
); | ||
}; | ||
|
||
export default NatAmountInput; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
// @ts-check | ||
import { assert, details } from '@agoric/assert'; | ||
import { MathKind } from '@agoric/ertp'; | ||
import '@agoric/ertp/exported'; | ||
|
||
import { parseAsNat } from './natValue/parseAsNat'; | ||
import { stringifyNat } from './natValue/stringifyNat'; | ||
import { parseAsSet } from './setValue/parseAsSet'; | ||
import { stringifySet } from './setValue/stringifySet'; | ||
|
||
/** | ||
* | ||
* @param {string} str - string to parse as a value | ||
* @param {AmountMathKind} [mathKind] - mathKind of the value | ||
* @param {number} [decimalPlaces] - places to move the decimal to the left | ||
* @returns {Value} | ||
*/ | ||
export const parseAsValue = ( | ||
str, | ||
mathKind = MathKind.NAT, | ||
decimalPlaces = 0, | ||
) => { | ||
if (mathKind === MathKind.NAT) { | ||
return parseAsNat(str, decimalPlaces); | ||
} | ||
if (mathKind === MathKind.SET) { | ||
return parseAsSet(str); | ||
} | ||
assert.fail(details`MathKind ${mathKind} must be NAT or SET`); | ||
}; | ||
|
||
/** | ||
* @param {string} str - string to parse as a value | ||
* @param {Brand} brand - brand to use in the amount | ||
* @param {AmountMathKind} [mathKind] - mathKind of the value | ||
* @param {number} [decimalPlaces] - places to move the decimal to the left | ||
* @returns {Amount} | ||
*/ | ||
export const parseAsAmount = ( | ||
str, | ||
brand, | ||
mathKind = MathKind.NAT, | ||
decimalPlaces = 0, | ||
) => { | ||
return { brand, value: parseAsValue(str, mathKind, decimalPlaces) }; | ||
}; | ||
|
||
/** | ||
* | ||
* @param {Value} value - value to stringify | ||
* @param {AmountMathKind} [mathKind] - mathKind of the value | ||
* @param {number} [decimalPlaces] - places to move the decimal to the | ||
* right in the string | ||
* @param {number} [placesToShow] - places after the decimal to show | ||
* @returns {string} | ||
*/ | ||
export const stringifyValue = ( | ||
value, | ||
mathKind = MathKind.NAT, | ||
decimalPlaces = 0, | ||
placesToShow = 2, | ||
) => { | ||
if (mathKind === MathKind.NAT) { | ||
// @ts-ignore Value is a Nat | ||
return stringifyNat(value, decimalPlaces, placesToShow); | ||
} | ||
if (mathKind === MathKind.SET) { | ||
// @ts-ignore Value is a SetValue | ||
return stringifySet(value); | ||
} | ||
assert.fail(details`MathKind ${mathKind} must be NAT or SET`); | ||
}; | ||
|
||
/** | ||
* Stringify the value of a purse | ||
* | ||
* @param {any} purse | ||
* @returns {string} | ||
*/ | ||
export const stringifyPurseValue = purse => { | ||
if (!purse) { | ||
return '0'; | ||
} | ||
return stringifyValue( | ||
purse.value, | ||
purse.displayInfo.mathKind, | ||
purse.displayInfo.decimalPlaces, | ||
); | ||
}; | ||
|
||
/** | ||
* Stringify the value in an amount | ||
* | ||
* @param {Amount} amount | ||
* @param {AmountMathKind} [mathKind] - mathKind of the value | ||
* @param {number} [decimalPlaces] - places to move the decimal to the | ||
* right in the string | ||
* @param {number} [placesToShow] - places after the decimal to show | ||
* @returns {string} | ||
*/ | ||
export function stringifyAmountValue( | ||
amount, | ||
mathKind, | ||
decimalPlaces, | ||
placesToShow, | ||
) { | ||
if (!amount) { | ||
return '0'; | ||
} | ||
return stringifyValue(amount.value, mathKind, decimalPlaces, placesToShow); | ||
} |
Oops, something went wrong.