├── .eslintrc
├── .gitignore
├── .nvmrc
├── .prettierrc
├── .storybook
├── addons.js
├── config.js
└── webpack.config.js
├── .travis.yml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── config
├── env.js
├── jest
│ ├── cssTransform.js
│ └── fileTransform.js
├── paths.js
├── polyfills.js
├── webpack.config.demo.js
├── webpack.config.dev.js
├── webpack.config.prod.js
└── webpackDevServer.config.js
├── jest-test-results.json
├── package-lock.json
├── package.json
├── public
├── favicon.ico
├── index.html
└── manifest.json
├── scripts
├── build.js
├── demo.js
├── start.js
└── test.js
├── src
├── assets
│ ├── inrupt_logo.png
│ ├── shexj.json
│ └── solid_logo.png
├── demo
│ ├── App.js
│ ├── components
│ │ ├── HandleShexForm
│ │ │ ├── handle-shex-form.component.js
│ │ │ └── index.js
│ │ └── index.js
│ ├── index.js
│ └── registerServiceWorker.js
├── lib
│ ├── classes
│ │ ├── access-control-factory.js
│ │ ├── access-control-list.js
│ │ ├── access-control-list.test.js
│ │ ├── app-permissions.js
│ │ ├── index.js
│ │ ├── notification.js
│ │ └── notifications.test.js
│ ├── components
│ │ ├── FormModel
│ │ │ ├── children
│ │ │ │ ├── Form
│ │ │ │ │ └── UI
│ │ │ │ │ │ ├── CheckBox
│ │ │ │ │ │ ├── check-box.component.js
│ │ │ │ │ │ ├── check-box.styles.js
│ │ │ │ │ │ ├── check-box.test.js
│ │ │ │ │ │ └── index.js
│ │ │ │ │ │ ├── CheckBoxList
│ │ │ │ │ │ ├── check-box-list.component.js
│ │ │ │ │ │ ├── check-box-list.test.js
│ │ │ │ │ │ └── index.js
│ │ │ │ │ │ ├── Classifier
│ │ │ │ │ │ ├── classifier.component.js
│ │ │ │ │ │ ├── classifier.style.js
│ │ │ │ │ │ └── index.js
│ │ │ │ │ │ ├── ColorPicker
│ │ │ │ │ │ ├── color-picker.component.js
│ │ │ │ │ │ ├── color-picker.styles.js
│ │ │ │ │ │ ├── color-picker.test.js
│ │ │ │ │ │ └── index.js
│ │ │ │ │ │ ├── Comment
│ │ │ │ │ │ ├── comment.component.js
│ │ │ │ │ │ ├── comment.test.js
│ │ │ │ │ │ └── index.js
│ │ │ │ │ │ ├── DateTimePicker
│ │ │ │ │ │ ├── date-time-picker.component.js
│ │ │ │ │ │ ├── date-time-picker.test.js
│ │ │ │ │ │ ├── date-time.styles.js
│ │ │ │ │ │ └── index.js
│ │ │ │ │ │ ├── Decimal
│ │ │ │ │ │ ├── decimal.component.js
│ │ │ │ │ │ ├── decimal.test.js
│ │ │ │ │ │ └── index.js
│ │ │ │ │ │ ├── DeleteButton
│ │ │ │ │ │ ├── delete-button.component.js
│ │ │ │ │ │ ├── delete-button.test.js
│ │ │ │ │ │ └── index.js
│ │ │ │ │ │ ├── Email
│ │ │ │ │ │ ├── email.component.js
│ │ │ │ │ │ ├── email.test.js
│ │ │ │ │ │ └── index.js
│ │ │ │ │ │ ├── ErrorMessage
│ │ │ │ │ │ ├── error-message.component.js
│ │ │ │ │ │ ├── error-message.styled.js
│ │ │ │ │ │ └── index.js
│ │ │ │ │ │ ├── Float
│ │ │ │ │ │ ├── float.component.js
│ │ │ │ │ │ ├── float.test.js
│ │ │ │ │ │ └── index.js
│ │ │ │ │ │ ├── Heading
│ │ │ │ │ │ ├── heading.component.js
│ │ │ │ │ │ ├── heading.test.js
│ │ │ │ │ │ └── index.js
│ │ │ │ │ │ ├── Input
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── input.component.js
│ │ │ │ │ │ ├── input.styles.js
│ │ │ │ │ │ └── input.test.js
│ │ │ │ │ │ ├── Integer
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── integer.component.js
│ │ │ │ │ │ └── integer.test.js
│ │ │ │ │ │ ├── Phone
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── phone.component.js
│ │ │ │ │ │ └── phone.test.js
│ │ │ │ │ │ ├── RadioButton
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── radio-button.component.js
│ │ │ │ │ │ └── radio-button.test.js
│ │ │ │ │ │ ├── RadioButtonList
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── radio-button-list.component.js
│ │ │ │ │ │ └── radio-button-list.test.js
│ │ │ │ │ │ ├── Select
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── select.component.js
│ │ │ │ │ │ └── select.test.js
│ │ │ │ │ │ ├── TextArea
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── text-area.component.js
│ │ │ │ │ │ ├── text-area.styles.js
│ │ │ │ │ │ └── text-area.test.js
│ │ │ │ │ │ ├── component-mapping.js
│ │ │ │ │ │ └── index.js
│ │ │ │ ├── Group
│ │ │ │ │ ├── group.component.js
│ │ │ │ │ ├── group.style.js
│ │ │ │ │ └── index.js
│ │ │ │ ├── Multiple
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── multiple.component.js
│ │ │ │ ├── Spinner
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── spinner.component.js
│ │ │ │ └── Viewer
│ │ │ │ │ ├── UI
│ │ │ │ │ ├── BoolLine
│ │ │ │ │ │ ├── bool-line.component.js
│ │ │ │ │ │ ├── bool-line.style.js
│ │ │ │ │ │ ├── bool-line.test.js
│ │ │ │ │ │ └── index.js
│ │ │ │ │ ├── ColorLine
│ │ │ │ │ │ ├── color-line.component.js
│ │ │ │ │ │ ├── color-line.style.js
│ │ │ │ │ │ ├── color-line.test.js
│ │ │ │ │ │ └── index.js
│ │ │ │ │ ├── DateLine
│ │ │ │ │ │ ├── date-line.component.js
│ │ │ │ │ │ ├── date-line.style.js
│ │ │ │ │ │ ├── date-line.test.js
│ │ │ │ │ │ └── index.js
│ │ │ │ │ ├── MultiLine
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── multi-line.component.js
│ │ │ │ │ │ ├── multi-line.style.js
│ │ │ │ │ │ └── multi-line.test.js
│ │ │ │ │ ├── MultipleViewer
│ │ │ │ │ │ └── multiple-viewer.component.js
│ │ │ │ │ ├── SingleLine
│ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ ├── single-line.component.js
│ │ │ │ │ │ ├── single-line.style.js
│ │ │ │ │ │ └── single-line.test.js
│ │ │ │ │ └── ui-mapping.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── viewer.component.js
│ │ │ │ │ └── viewer.style.js
│ │ │ ├── form-model-example.json
│ │ │ ├── form-model.component.js
│ │ │ ├── index.js
│ │ │ └── live-form-model.component.js
│ │ ├── PrivateRoute
│ │ │ ├── index.js
│ │ │ ├── private-route.component.js
│ │ │ ├── private-route.component.test.js
│ │ │ └── private-route.style.js
│ │ ├── ProfileUploader
│ │ │ ├── index.js
│ │ │ ├── profile-uploader.component.js
│ │ │ ├── profile-uploader.style.js
│ │ │ └── profile-uploader.test.js
│ │ ├── ProfileViewer
│ │ │ ├── index.js
│ │ │ ├── profile-viewer.component.js
│ │ │ └── profile-viewer.style.js
│ │ ├── ProviderLogin
│ │ │ ├── children
│ │ │ │ └── Form
│ │ │ │ │ ├── form.presentational.js
│ │ │ │ │ └── index.js
│ │ │ ├── index.js
│ │ │ ├── provider-login.container.js
│ │ │ └── provider-login.container.test.js
│ │ ├── ProviderSelect
│ │ │ ├── index.js
│ │ │ ├── provider.select.component.js
│ │ │ ├── provider.select.component.test.js
│ │ │ └── styled.components.js
│ │ ├── ShexForm
│ │ │ ├── children
│ │ │ │ ├── AddButton
│ │ │ │ │ ├── add-button.component.js
│ │ │ │ │ ├── add-button.component.test.js
│ │ │ │ │ └── index.js
│ │ │ │ ├── DeleteButton
│ │ │ │ │ ├── delete-button.component.js
│ │ │ │ │ ├── delete-button.component.test.js
│ │ │ │ │ └── index.js
│ │ │ │ ├── DropDownField
│ │ │ │ │ ├── dropdown-field.component.js
│ │ │ │ │ ├── dropdown-field.component.test.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── styled.component.js
│ │ │ │ ├── Field
│ │ │ │ │ ├── field.component.js
│ │ │ │ │ ├── field.component.test.js
│ │ │ │ │ └── index.js
│ │ │ │ ├── InputField
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── input-field.component.js
│ │ │ │ │ ├── input-field.component.test.js
│ │ │ │ │ └── styled.component.js
│ │ │ │ ├── expression-fields.component.js
│ │ │ │ └── index.js
│ │ │ ├── index.js
│ │ │ ├── shex-form.component.js
│ │ │ ├── shexj.json
│ │ │ └── styled.component.js
│ │ ├── ShexFormBuilder
│ │ │ ├── children
│ │ │ │ └── ShexFormLive
│ │ │ │ │ ├── index.js
│ │ │ │ │ ├── shex-form-live.component.js
│ │ │ │ │ └── styled.component.js
│ │ │ ├── index.js
│ │ │ ├── shex-form-builder.component.js
│ │ │ └── shex-form-builder.component.test.js
│ │ ├── Uploader
│ │ │ ├── index.js
│ │ │ ├── uploader.component.js
│ │ │ └── uploader.test.js
│ │ ├── index.js
│ │ └── withAuthorization
│ │ │ ├── index.js
│ │ │ ├── with-authorization.component.js
│ │ │ └── with-authorization.test.js
│ ├── constants
│ │ └── index.js
│ ├── context
│ │ ├── ThemeContext.js
│ │ ├── formModel.provider.js
│ │ ├── index.js
│ │ └── shex.provider.js
│ ├── entities
│ │ └── index.js
│ ├── hooks
│ │ ├── index.js
│ │ ├── useNotification.js
│ │ ├── useNotification.test.js
│ │ ├── useShex.js
│ │ └── useShex.test.js
│ ├── index.js
│ ├── shapes
│ │ └── notification.json
│ ├── styled-components
│ │ ├── form.js
│ │ └── index.js
│ └── utils
│ │ ├── datestimes.test.js
│ │ ├── datetimes.js
│ │ ├── error.js
│ │ ├── index.js
│ │ ├── shex.js
│ │ ├── shexFormValidator.js
│ │ ├── solidFetch.js
│ │ └── statusMessage.js
└── test
│ └── __mocks__
│ ├── @solid
│ └── query-ldflex.js
│ └── solid-auth-client.js
└── stories
├── Image
├── README.md
└── image.stories.js
├── LogoutButton
├── README.md
└── logout-button.stories.js
├── PrivateRoute
├── README.md
└── private-route.stories.js
├── ProfileUploader
├── README.md
└── profile-uploader.stories.js
├── ProviderLogin
├── README.md
└── provider-login.stories.js
├── ShexForm
├── README.md
└── shex-form.stories.js
├── Uploader
├── README.md
└── uploader.stories.js
├── withAuthorization
├── README.md
└── with-authorization.stories.js
└── withWebId
├── README.md
└── with-webid.stories.js
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "babel-eslint",
3 | "extends": ["react-app", "airbnb", "prettier"],
4 | "plugins": ["react", "prettier"],
5 | "rules": {
6 | "prettier/prettier": [1],
7 | "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }],
8 | "no-underscore-dangle": [0],
9 | "import/no-unresolved": [0],
10 | "no-unused-vars": [1],
11 | "react/prop-types": [1],
12 | "no-shadow": [0],
13 | "no-restricted-syntax": [0],
14 | "consistent-return": [0],
15 | "import/prefer-default-export": [0],
16 | "import/no-cycle": [0],
17 | "quotes": [1, "single"],
18 | "react/no-array-index-key": [1],
19 | "react/jsx-one-expression-per-line": [0],
20 | "jsx-a11y/label-has-for": [0]
21 | },
22 | "settings": {
23 | "import/resolver": { "babel-module": {} }
24 | },
25 | "parserOptions": {
26 | "ecmaFeatures": {
27 | "jsx": true,
28 | "modules": true
29 | }
30 | },
31 | "env": {
32 | "browser": true,
33 | "jest": true
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 |
6 | # production
7 | /build
8 | /demo
9 |
10 | # testing
11 | /coverage
12 |
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | # editors
22 | .idea
23 | *.iml
24 |
25 | npm-debug.log*
26 | yarn-debug.log*
27 | yarn-error.log*
28 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | v12.7.0
2 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "printWidth": 100
4 | }
5 |
--------------------------------------------------------------------------------
/.storybook/addons.js:
--------------------------------------------------------------------------------
1 | import '@storybook/addons';
2 | import '@storybook/addon-console';
3 | import 'storybook-readme/register';
4 | import '@storybook/addon-knobs/register';
5 | import '@storybook/addon-actions/register';
6 | import '@storybook/addon-jest/register';
7 | import 'storybook-addon-jsx/register';
8 |
--------------------------------------------------------------------------------
/.storybook/config.js:
--------------------------------------------------------------------------------
1 | import { configure, addDecorator } from '@storybook/react';
2 | import { addReadme } from 'storybook-readme';
3 | import { withTests } from '@storybook/addon-jest';
4 | import StoryRouter from 'storybook-react-router';
5 |
6 | import results from '../jest-test-results.json';
7 |
8 | import { jsxDecorator } from 'storybook-addon-jsx';
9 |
10 | addDecorator(jsxDecorator);
11 |
12 | addDecorator(
13 | withTests({
14 | results
15 | })
16 | );
17 | addDecorator(addReadme);
18 |
19 | addDecorator(StoryRouter());
20 |
21 | // automatically import all files ending in *.stories.js
22 | const req = require.context('../stories', true, /.stories.js$/);
23 | function loadStories() {
24 | req.keys().forEach(filename => req(filename));
25 | }
26 |
27 | configure(loadStories, module);
28 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - 'node'
4 | script:
5 | - npm run test
6 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to the Solid React Components Library
2 |
3 | Thank you for your interest in contributing to the Solid React Components Library!
4 |
5 | Before getting started, please review the [Solid React SDK Contributor Guide](https://github.com/Inrupt-inc/solid-react-sdk/blob/master/CONTRIBUTING.md).
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Inrupt
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 |
--------------------------------------------------------------------------------
/config/env.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 | const paths = require('./paths');
4 |
5 | // Make sure that including paths.js after env.js will read .env variables.
6 | delete require.cache[require.resolve('./paths')];
7 |
8 | const NODE_ENV = process.env.NODE_ENV;
9 | if (!NODE_ENV) {
10 | throw new Error('The NODE_ENV environment variable is required but was not specified.');
11 | }
12 |
13 | // https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
14 | var dotenvFiles = [
15 | `${paths.dotenv}.${NODE_ENV}.local`,
16 | `${paths.dotenv}.${NODE_ENV}`,
17 | // Don't include `.env.local` for `test` environment
18 | // since normally you expect tests to produce the same
19 | // results for everyone
20 | NODE_ENV !== 'test' && `${paths.dotenv}.local`,
21 | paths.dotenv
22 | ].filter(Boolean);
23 |
24 | // Load environment variables from .env* files. Suppress warnings using silent
25 | // if this file is missing. dotenv will never modify any environment variables
26 | // that have already been set.
27 | // https://github.com/motdotla/dotenv
28 | dotenvFiles.forEach(dotenvFile => {
29 | if (fs.existsSync(dotenvFile)) {
30 | require('dotenv').config({
31 | path: dotenvFile
32 | });
33 | }
34 | });
35 |
36 | // We support resolving modules according to `NODE_PATH`.
37 | // This lets you use absolute paths in imports inside large monorepos:
38 | // https://github.com/facebookincubator/create-react-app/issues/253.
39 | // It works similar to `NODE_PATH` in Node itself:
40 | // https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders
41 | // Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored.
42 | // Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims.
43 | // https://github.com/facebookincubator/create-react-app/issues/1023#issuecomment-265344421
44 | // We also resolve them to make sure all tools using them work consistently.
45 | const appDirectory = fs.realpathSync(process.cwd());
46 | process.env.NODE_PATH = (process.env.NODE_PATH || '')
47 | .split(path.delimiter)
48 | .filter(folder => folder && !path.isAbsolute(folder))
49 | .map(folder => path.resolve(appDirectory, folder))
50 | .join(path.delimiter);
51 |
52 | // Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be
53 | // injected into the application via DefinePlugin in Webpack configuration.
54 | const REACT_APP = /^REACT_APP_/i;
55 |
56 | function getClientEnvironment(publicUrl) {
57 | const raw = Object.keys(process.env)
58 | .filter(key => REACT_APP.test(key))
59 | .reduce(
60 | (env, key) => {
61 | env[key] = process.env[key];
62 | return env;
63 | },
64 | {
65 | // Useful for determining whether we’re running in production mode.
66 | // Most importantly, it switches React into the correct mode.
67 | NODE_ENV: process.env.NODE_ENV || 'development',
68 | // Useful for resolving the correct path to static assets in `public`.
69 | // For example,
.
70 | // This should only be used as an escape hatch. Normally you would put
71 | // images into the `src` and `import` them in code to get their paths.
72 | PUBLIC_URL: publicUrl
73 | }
74 | );
75 | // Stringify all values so we can feed into Webpack DefinePlugin
76 | const stringified = {
77 | 'process.env': Object.keys(raw).reduce((env, key) => {
78 | env[key] = JSON.stringify(raw[key]);
79 | return env;
80 | }, {})
81 | };
82 |
83 | return { raw, stringified };
84 | }
85 |
86 | module.exports = getClientEnvironment;
87 |
--------------------------------------------------------------------------------
/config/jest/cssTransform.js:
--------------------------------------------------------------------------------
1 | // This is a custom Jest transformer turning style imports into empty objects.
2 | // http://facebook.github.io/jest/docs/tutorial-webpack.html
3 |
4 | module.exports = {
5 | process() {
6 | return 'module.exports = {};';
7 | },
8 | getCacheKey() {
9 | // The output is always the same.
10 | return 'cssTransform';
11 | }
12 | };
13 |
--------------------------------------------------------------------------------
/config/jest/fileTransform.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | // This is a custom Jest transformer turning file imports into filenames.
4 | // http://facebook.github.io/jest/docs/tutorial-webpack.html
5 |
6 | module.exports = {
7 | process(src, filename) {
8 | return `module.exports = ${JSON.stringify(path.basename(filename))};`;
9 | }
10 | };
11 |
--------------------------------------------------------------------------------
/config/paths.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/no-dynamic-require */
2 | /* eslint-disable global-require */
3 | const path = require('path');
4 | const fs = require('fs');
5 | const url = require('url');
6 |
7 | // Make sure any symlinks in the project folder are resolved:
8 | // https://github.com/facebook/create-react-app/issues/637
9 | const appDirectory = fs.realpathSync(process.cwd());
10 | const resolveApp = relativePath => path.resolve(appDirectory, relativePath);
11 |
12 | const envPublicUrl = process.env.PUBLIC_URL;
13 |
14 | function ensureSlash(inputPath, needsSlash) {
15 | const hasSlash = inputPath.endsWith('/');
16 | if (hasSlash && !needsSlash) {
17 | return inputPath.substr(0, inputPath.length - 1);
18 | }
19 | if (!hasSlash && needsSlash) {
20 | return `${inputPath}/`;
21 | }
22 | return inputPath;
23 | }
24 |
25 | const getPublicUrl = appPackageJson => envPublicUrl || require(appPackageJson).homepage;
26 |
27 | // We use `PUBLIC_URL` environment variable or "homepage" field to infer
28 | // "public path" at which the app is served.
29 | // Webpack needs to know it to put the right