├── .babelrc
├── .github
├── ISSUE_TEMPLATE
│ ├── BUG_REPORT.yml
│ └── FEATURE_REQUEST.yml
├── release-drafter-v0.x.yml
├── release-drafter.yml
└── workflows
│ ├── npm-publish.yml
│ ├── release-drafter.yml
│ ├── storybook.yml
│ └── tests.yml
├── .gitignore
├── .npmignore
├── .prettierrc
├── .storybook
├── DocsPage.tsx
├── TableOfContent.tsx
├── doc-root.css
├── main.ts
├── manager-head.html
└── preview.tsx
├── .vim
└── coc-settings.json
├── .vscode
├── extensions.json
├── launch.json
└── settings.json
├── .yarn
├── plugins
│ └── @yarnpkg
│ │ └── plugin-workspace-tools.cjs
├── releases
│ └── yarn-4.5.1.cjs
├── sdks
│ ├── eslint
│ │ ├── bin
│ │ │ └── eslint.js
│ │ ├── lib
│ │ │ ├── api.js
│ │ │ ├── types
│ │ │ │ ├── index.d.ts
│ │ │ │ ├── rules
│ │ │ │ │ └── index.d.ts
│ │ │ │ ├── universal.d.ts
│ │ │ │ └── use-at-your-own-risk.d.ts
│ │ │ ├── universal.js
│ │ │ └── unsupported-api.js
│ │ └── package.json
│ ├── integrations.yml
│ ├── prettier
│ │ ├── bin
│ │ │ └── prettier.cjs
│ │ ├── index.cjs
│ │ └── package.json
│ └── typescript
│ │ ├── bin
│ │ ├── tsc
│ │ └── tsserver
│ │ ├── lib
│ │ ├── tsc.js
│ │ ├── tsserver.js
│ │ ├── tsserverlibrary.js
│ │ └── typescript.js
│ │ └── package.json
└── versions
│ └── 9085f262.yml
├── .yarnrc.yml
├── LICENSE
├── README.md
├── eslint.config.mjs
├── package.json
├── public
├── favicon.ico
├── faviconGlobe.ico
├── faviconReact.ico
└── faviconTS.ico
├── src
├── __mocks__
│ └── fileMock.js
├── components
│ ├── assets
│ │ └── img
│ │ │ ├── forbidden.png
│ │ │ ├── logo.png
│ │ │ ├── miniLogo.png
│ │ │ └── notFound.png
│ ├── buttons
│ │ ├── BackToButton
│ │ │ ├── BackToButton.test.tsx
│ │ │ ├── BackToButton.tsx
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ ├── Button
│ │ │ ├── Button.test.tsx
│ │ │ ├── Button.tsx
│ │ │ ├── ButtonStyles.ts
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ ├── IconButton
│ │ │ ├── IconButton.test.tsx
│ │ │ ├── IconButton.tsx
│ │ │ ├── IconButtonStyles.ts
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ └── UploadButton
│ │ │ ├── UploadButton.test.tsx
│ │ │ ├── UploadButton.tsx
│ │ │ ├── index.ts
│ │ │ ├── types.ts
│ │ │ └── uploadButtonValidators.ts
│ ├── charts
│ │ ├── DeprecatedChart
│ │ │ ├── DeprecatedChart.tsx
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ └── DeprecatedStatsChart
│ │ │ ├── DeprecatedStatsChart.tsx
│ │ │ ├── DeprecatedStatsChartStyles.ts
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ ├── dataDisplay
│ │ ├── ExpandingText
│ │ │ ├── ExpandingText.test.tsx
│ │ │ ├── ExpandingText.tsx
│ │ │ ├── ExpandingTextStyles.ts
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ ├── FavIcon
│ │ │ ├── FavIcon.tsx
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ ├── StatsChart
│ │ │ ├── Chart.tsx
│ │ │ ├── StatsChart.test.tsx
│ │ │ ├── StatsChart.tsx
│ │ │ ├── StatsChartStyles.ts
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ └── Typography
│ │ │ ├── Typography.test.tsx
│ │ │ ├── Typography.tsx
│ │ │ ├── TypographyStyles.ts
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ ├── feedback
│ │ ├── Dialog
│ │ │ ├── Dialog.test.tsx
│ │ │ ├── Dialog.tsx
│ │ │ ├── DialogStyles.ts
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ ├── FakeText
│ │ │ ├── FakeText.test.tsx
│ │ │ ├── FakeText.tsx
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ ├── Forbidden
│ │ │ ├── Forbidden.test.tsx
│ │ │ ├── Forbidden.tsx
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ ├── LinearProgress
│ │ │ ├── LinearProgress.test.tsx
│ │ │ ├── LinearProgress.tsx
│ │ │ ├── LinearProgressStyles.ts
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ ├── NotFound
│ │ │ ├── NotFound.test.tsx
│ │ │ ├── NotFound.tsx
│ │ │ ├── NotFoundStyles.ts
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ └── Toast
│ │ │ ├── Toast.test.tsx
│ │ │ ├── ToastContainer.tsx
│ │ │ ├── ToastStyles.ts
│ │ │ ├── index.ts
│ │ │ ├── types.ts
│ │ │ ├── usePromiseToast.ts
│ │ │ ├── useToast.tsx
│ │ │ └── utils.tsx
│ ├── index.ts
│ ├── inputs
│ │ ├── Autocomplete
│ │ │ ├── Autocomplete.test.tsx
│ │ │ ├── Autocomplete.tsx
│ │ │ ├── Option.tsx
│ │ │ ├── index.ts
│ │ │ ├── types.ts
│ │ │ └── utils.ts
│ │ ├── DateTime
│ │ │ ├── DateTime.test.tsx
│ │ │ ├── DateTime.tsx
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ ├── DeprecatedAutocomplete
│ │ │ ├── DeprecatedAutocomplete.test.tsx
│ │ │ ├── DeprecatedAutocomplete.tsx
│ │ │ ├── DeprecatedAutocompleteStyles.ts
│ │ │ ├── Option.tsx
│ │ │ ├── index.ts
│ │ │ ├── types.ts
│ │ │ └── utils.ts
│ │ ├── DynamicField
│ │ │ ├── DynamicField.test.tsx
│ │ │ ├── DynamicField.tsx
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ ├── PasswordField
│ │ │ ├── PasswordField.test.tsx
│ │ │ ├── PasswordField.tsx
│ │ │ └── index.ts
│ │ ├── Slider
│ │ │ ├── Slider.test.tsx
│ │ │ ├── Slider.tsx
│ │ │ ├── SliderStyles.ts
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ ├── Tags
│ │ │ ├── DisplayTags.tsx
│ │ │ ├── Tags.test.tsx
│ │ │ ├── TagsInput.tsx
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ └── TextField
│ │ │ ├── TextField.test.tsx
│ │ │ ├── TextField.tsx
│ │ │ ├── TextFieldStyles.ts
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ ├── navigation
│ │ ├── NavPills
│ │ │ ├── NavPills.test.tsx
│ │ │ ├── NavPills.tsx
│ │ │ ├── NavPillsStyles.ts
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ ├── Pagination
│ │ │ ├── Pagination.test.tsx
│ │ │ ├── Pagination.tsx
│ │ │ ├── PaginationStyles.ts
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ └── SideMenu
│ │ │ ├── SideMenu.test.tsx
│ │ │ ├── SideMenu.tsx
│ │ │ ├── SideMenuStyles.ts
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ ├── surfaces
│ │ ├── Accordion
│ │ │ ├── Accordion.test.tsx
│ │ │ ├── Accordion.tsx
│ │ │ ├── AccordionStyles.ts
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ ├── Card
│ │ │ ├── Card.test.tsx
│ │ │ ├── Card.tsx
│ │ │ ├── CardActions
│ │ │ │ ├── CardActions.test.tsx
│ │ │ │ ├── CardActions.tsx
│ │ │ │ ├── CardActionsStyles.ts
│ │ │ │ └── index.ts
│ │ │ ├── CardHeader
│ │ │ │ ├── CardHeader.test.tsx
│ │ │ │ ├── CardHeader.tsx
│ │ │ │ ├── CardHeaderStyles.ts
│ │ │ │ └── index.ts
│ │ │ ├── CardStyles.ts
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ ├── CollapseCard
│ │ │ ├── CollapseCard.test.tsx
│ │ │ ├── CollapseCard.tsx
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ └── StatsCard
│ │ │ ├── StatsCard.test.tsx
│ │ │ ├── StatsCard.tsx
│ │ │ ├── StatsCardStyles.ts
│ │ │ ├── _mocks.ts
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ ├── themes
│ │ ├── blueTheme.ts
│ │ ├── common
│ │ │ ├── overrides
│ │ │ │ ├── Autocomplete.ts
│ │ │ │ ├── Button.ts
│ │ │ │ ├── Card.ts
│ │ │ │ ├── Chip.ts
│ │ │ │ ├── Divider.ts
│ │ │ │ ├── TextField.ts
│ │ │ │ └── index.ts
│ │ │ ├── palette
│ │ │ │ ├── basicColors.ts
│ │ │ │ └── index.ts
│ │ │ ├── shadows.ts
│ │ │ ├── table.ts
│ │ │ └── typography.ts
│ │ ├── defaultTheme.ts
│ │ ├── greenTheme.ts
│ │ ├── index.ts
│ │ ├── lightBlueTheme.ts
│ │ ├── orangeTheme.ts
│ │ ├── redTheme.ts
│ │ ├── types.ts
│ │ └── vividOrangeTheme.ts
│ ├── types.ts
│ └── utils
│ │ ├── constants.ts
│ │ └── useDebouncedCallback.ts
├── global.d.ts
├── setupTests.ts
├── stories
│ ├── Introduction.stories.tsx
│ ├── _introduction
│ │ ├── about
│ │ │ ├── AboutContainer.tsx
│ │ │ └── AboutStyles.ts
│ │ ├── constants
│ │ │ └── orbits.ts
│ │ └── orbits
│ │ │ ├── OrbitContainer.tsx
│ │ │ ├── OrbitStyles.ts
│ │ │ └── OrbitSwitch.tsx
│ ├── assets
│ │ ├── audio
│ │ │ └── rain-ambient.mp3
│ │ ├── img
│ │ │ ├── robot.png
│ │ │ ├── rocket.png
│ │ │ ├── satellite.png
│ │ │ └── spaceship.png
│ │ └── storyImg
│ │ │ ├── code-brackets.svg
│ │ │ ├── colors.svg
│ │ │ ├── comments.svg
│ │ │ ├── direction.svg
│ │ │ ├── flow.svg
│ │ │ ├── plugin.svg
│ │ │ ├── repo.svg
│ │ │ └── stackalt.svg
│ ├── buttons
│ │ ├── BackToButton
│ │ │ └── BackToButton.stories.tsx
│ │ ├── Button
│ │ │ ├── Button.stories.tsx
│ │ │ ├── ColorsPreview.tsx
│ │ │ ├── LoadingPreview.tsx
│ │ │ ├── SizesPreview.tsx
│ │ │ └── WithIconPreview.tsx
│ │ ├── IconButton
│ │ │ ├── ColorsPreview.tsx
│ │ │ ├── IconButton.stories.tsx
│ │ │ ├── LoadingPreview.tsx
│ │ │ ├── SizesPreview.tsx
│ │ │ └── TypesPreview.tsx
│ │ └── UploadButton
│ │ │ ├── CustomIconsPreview.tsx
│ │ │ ├── IconPropsPreview.tsx
│ │ │ ├── InputTypesPreview.tsx
│ │ │ ├── MobileCapturePreview.tsx
│ │ │ ├── MultipleSelectionPreview.tsx
│ │ │ ├── SizesPreview.tsx
│ │ │ └── UploadButton.stories.tsx
│ ├── charts
│ │ ├── DeprecatedChart
│ │ │ ├── DeprecatedChart.stories.tsx
│ │ │ └── _mocks.ts
│ │ └── DeprecatedStatsChart
│ │ │ ├── BarPreview.tsx
│ │ │ ├── DeprecatedStatsChart.stories.tsx
│ │ │ ├── LinePreview.tsx
│ │ │ └── _mocks.ts
│ ├── dataDisplay
│ │ ├── ExpandingText
│ │ │ ├── DisplayPreview.tsx
│ │ │ └── ExpandingText.stories.tsx
│ │ ├── FavIcon
│ │ │ └── FavIcon.stories.tsx
│ │ ├── StatsChart
│ │ │ └── StatsChart.stories.tsx
│ │ └── Typography
│ │ │ ├── ColorsPreview.tsx
│ │ │ ├── ExtraStylingPreview.tsx
│ │ │ ├── Typography.stories.tsx
│ │ │ └── VariantsPreview.tsx
│ ├── feedback
│ │ ├── Dialog
│ │ │ ├── ActionsPreview.tsx
│ │ │ ├── DefaultPreview.tsx
│ │ │ ├── Dialog.stories.tsx
│ │ │ └── _mocks.tsx
│ │ ├── FakeText
│ │ │ ├── AnimationsPreview.tsx
│ │ │ ├── FakeText.stories.tsx
│ │ │ └── VariantsPreview.tsx
│ │ ├── Forbidden
│ │ │ └── Forbidden.stories.tsx
│ │ ├── LinearProgress
│ │ │ ├── ColorsPreview.tsx
│ │ │ ├── GlobalPreview.tsx
│ │ │ ├── LinearProgress.stories.tsx
│ │ │ └── VariantsPreview.tsx
│ │ ├── NotFound
│ │ │ └── NotFound.stories.tsx
│ │ └── Toast
│ │ │ ├── ActionsPreview.tsx
│ │ │ ├── PositionsPreview.tsx
│ │ │ ├── TextSizePreview.tsx
│ │ │ ├── Toast.stories.tsx
│ │ │ ├── TransitionsPreview.tsx
│ │ │ └── VariantsPreview.tsx
│ ├── inputs
│ │ ├── Autocomplete
│ │ │ ├── Autocomplete.stories.tsx
│ │ │ ├── CreatablePreview.tsx
│ │ │ ├── CustomOptionPreview.tsx
│ │ │ ├── DefaultPreview.tsx
│ │ │ ├── GroupedPreview.tsx
│ │ │ ├── MultipleSelectionPreview.tsx
│ │ │ ├── OptionTypesPreview.tsx
│ │ │ ├── RequiredPreview.tsx
│ │ │ ├── _mocks.ts
│ │ │ └── components
│ │ │ │ ├── ColumnHeader.tsx
│ │ │ │ ├── ControlledCheckBox.tsx
│ │ │ │ └── FormattedJson.tsx
│ │ ├── DateTime
│ │ │ ├── ClearablePreview.tsx
│ │ │ ├── DateTime.stories.tsx
│ │ │ ├── DisabledPreview.tsx
│ │ │ ├── ErrorHelperTextPreview.tsx
│ │ │ └── FormatPreview.tsx
│ │ ├── DeprecatedAutocomplete
│ │ │ ├── CheckboxesPreview.tsx
│ │ │ ├── CreatablePreview.tsx
│ │ │ ├── CustomOptionPreview.tsx
│ │ │ ├── DefaultPreview.tsx
│ │ │ ├── DeprecatedAutocomplete.stories.tsx
│ │ │ ├── GroupedPreview.tsx
│ │ │ ├── MultipleSelectionPreview.tsx
│ │ │ ├── OptionTypesPreview.tsx
│ │ │ ├── RequiredPreview.tsx
│ │ │ ├── StylingPreview.tsx
│ │ │ ├── _mocks.ts
│ │ │ └── components
│ │ │ │ ├── ColumnHeader.tsx
│ │ │ │ ├── ControlledCheckBox.tsx
│ │ │ │ └── FormattedJson.tsx
│ │ ├── DynamicField
│ │ │ ├── ControlPreview.tsx
│ │ │ ├── DynamicControlPreview.tsx
│ │ │ ├── DynamicField.stories.tsx
│ │ │ ├── _hooks.ts
│ │ │ └── _mocks.ts
│ │ ├── PasswordField
│ │ │ ├── PasswordField.stories.tsx
│ │ │ ├── StatesPreview.tsx
│ │ │ └── VariantsPreview.tsx
│ │ ├── Slider
│ │ │ └── Slider.stories.tsx
│ │ ├── Tags
│ │ │ ├── ColorsPreview.tsx
│ │ │ ├── DefaultPreview.tsx
│ │ │ ├── Tags.stories.tsx
│ │ │ └── VariantsPreview.tsx
│ │ └── TextField
│ │ │ ├── ClearablePreview.tsx
│ │ │ ├── FormPropsPreview.tsx
│ │ │ ├── NumericPreview.tsx
│ │ │ ├── StepperPreview.tsx
│ │ │ ├── TextField.stories.tsx
│ │ │ ├── ValidationPreview.tsx
│ │ │ └── VariantsPreview.tsx
│ ├── navigation
│ │ ├── NavPills
│ │ │ ├── ControlledPreview.tsx
│ │ │ ├── FilledPreview.tsx
│ │ │ ├── NavPills.stories.tsx
│ │ │ ├── OrientationPreview.tsx
│ │ │ ├── WithActionsPreview.tsx
│ │ │ ├── WithIconsPreview.tsx
│ │ │ └── _options.tsx
│ │ ├── Pagination
│ │ │ ├── DefaultPreview.tsx
│ │ │ ├── Pagination.stories.tsx
│ │ │ ├── WithFirstAndLastPreview.tsx
│ │ │ └── WithNoCountPreview.tsx
│ │ └── SideMenu
│ │ │ ├── DefaultPreview.tsx
│ │ │ └── SideMenu.stories.tsx
│ └── surfaces
│ │ ├── Accordion
│ │ ├── Accordion.stories.tsx
│ │ ├── ActionsPreview.tsx
│ │ ├── ControlledPreview.tsx
│ │ └── _mocks.tsx
│ │ ├── Card
│ │ ├── BasicCardsPreview.tsx
│ │ ├── Card.stories.tsx
│ │ ├── FilledPreview.tsx
│ │ └── MediaPreview.tsx
│ │ ├── CollapseCard
│ │ ├── CollapseCard.stories.tsx
│ │ ├── ControlledPreview.tsx
│ │ └── FilledPreview.tsx
│ │ └── StatsCard
│ │ └── StatsCard.stories.tsx
└── testingUtils
│ ├── TestingWrapper.tsx
│ ├── index.ts
│ └── mocks.ts
├── tsconfig.build.json
├── tsconfig.json
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {"presets": ["@nrwl/js/babel"]}
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.yml:
--------------------------------------------------------------------------------
1 | name: Feature Request 🎇
2 | description: Suggest a new feature for Rocket-UI library.
3 | labels: [enhancement]
4 | body:
5 | - type: markdown
6 | attributes:
7 | value: |
8 | Thanks for contributing!
9 | - type: checkboxes
10 | attributes:
11 | label: Latest version
12 | description: We roll bug fixes, performance enhancements, and other improvements into new releases.
13 | options:
14 | - label: I have tested the latest version
15 | required: true
16 | - type: textarea
17 | id: feature-description
18 | attributes:
19 | label: Description
20 | description: Describe the new feature. How it should work.
21 | validations:
22 | required: true
23 | - type: textarea
24 | id: examples
25 | attributes:
26 | label: Examples
27 | description: Provide screenshots, examples of the expected behavior.
28 |
--------------------------------------------------------------------------------
/.github/release-drafter-v0.x.yml:
--------------------------------------------------------------------------------
1 | name-template: v$NEXT_PATCH_VERSION
2 | tag-template: v$NEXT_PATCH_VERSION
3 | categories:
4 | - title: 🚀 Features
5 | label: feature
6 | - title: 🐛 Bug Fixes
7 | label: fix
8 | - title: 🛠️ Maintenance
9 | label: chore
10 | change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
11 | commitish: 'support/0.x'
12 | filter-by-commitish: true
13 | template: |
14 | ## Changes
15 | $CHANGES
16 |
--------------------------------------------------------------------------------
/.github/release-drafter.yml:
--------------------------------------------------------------------------------
1 | name-template: v$NEXT_PATCH_VERSION
2 | tag-template: v$NEXT_PATCH_VERSION
3 | categories:
4 | - title: 🚀 Features
5 | label: feature
6 | - title: 🐛 Bug Fixes
7 | label: fix
8 | - title: 🛠️ Maintenance
9 | label: chore
10 | change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
11 | template: |
12 | ## Changes
13 | $CHANGES
--------------------------------------------------------------------------------
/.github/workflows/npm-publish.yml:
--------------------------------------------------------------------------------
1 | # This workflow will run tests using node and then publish a package to NPM when a release is created
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages
3 |
4 | name: npm-publish
5 |
6 | on:
7 | release:
8 | types: [published]
9 |
10 | concurrency:
11 | group: build-test-publish
12 |
13 | jobs:
14 | build-n-publish:
15 | runs-on: ubuntu-latest
16 | steps:
17 | - name: Checkout Repo
18 | uses: actions/checkout@master
19 | with:
20 | fetch-depth: 0
21 | - uses: actions/setup-node@v3
22 | with:
23 | node-version: 18.x
24 | registry-url: https://registry.npmjs.org/
25 | scope: '@totalsoft'
26 | - run: yarn -v
27 | - name: Install Dependencies
28 | run: yarn install
29 | - name: Build
30 | run: yarn build
31 | - name: Bump version
32 | run: yarn run version
33 | - name: Set npm authToken from env
34 | env:
35 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
36 | run: |
37 | yarn config &&
38 | yarn config set npmScopes.totalsoft.npmRegistryServer "https://registry.npmjs.org/" &&
39 | yarn config set npmScopes.totalsoft.npmAlwaysAuth true &&
40 | yarn config set npmScopes.totalsoft.npmAuthToken $NODE_AUTH_TOKEN
41 | - run: yarn publish
42 |
--------------------------------------------------------------------------------
/.github/workflows/release-drafter.yml:
--------------------------------------------------------------------------------
1 | name: Release Drafter
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | workflow_dispatch:
8 | inputs:
9 |
10 | jobs:
11 | update_release_draft:
12 | runs-on: ubuntu-latest
13 | steps:
14 | # Drafts your next Release notes as Pull Requests are merged into "master"
15 | - uses: release-drafter/release-drafter@v5
16 | env:
17 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
18 |
--------------------------------------------------------------------------------
/.github/workflows/storybook.yml:
--------------------------------------------------------------------------------
1 | # Copyright (c) TotalSoft.
2 | # This source code is licensed under the MIT license.
3 |
4 | name: Build and Deploy Storybook
5 | on:
6 | push:
7 | branches:
8 | - master
9 | paths: ['src/stories/**', 'src/components/**'] # Trigger the action only when files change in the folders defined here
10 | workflow_dispatch:
11 | permissions:
12 | contents: write
13 | jobs:
14 | storybook-build-and-deploy:
15 | runs-on: ubuntu-latest
16 | steps:
17 | - name: Checkout 🛎️
18 | uses: actions/checkout@v3
19 | with:
20 | persist-credentials: false
21 | - name: Install 🔧
22 | run: yarn install
23 | - name: Run tests ⚠️
24 | run: yarn test
25 | - name: Build 🔧
26 | run: yarn run build-storybook
27 | - name: Deploy 🚀
28 | uses: JamesIves/github-pages-deploy-action@3.6.2
29 | with:
30 | GITHUB_TOKEN: ${{ secrets.STORYBOOK_TOKEN }}
31 | BRANCH: gh-pages
32 | FOLDER: storybuild # The folder that the build-storybook script generates files.
33 | CLEAN: true # Automatically remove deleted files from the deploy branch
34 |
--------------------------------------------------------------------------------
/.github/workflows/tests.yml:
--------------------------------------------------------------------------------
1 | # This workflow will run tests using node and then publish a package to NPM when a release is created
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages
3 |
4 | name: run-tests
5 |
6 | on:
7 | pull_request:
8 | branches: [master]
9 |
10 | concurrency:
11 | group: build-test-publish
12 |
13 | jobs:
14 | release:
15 | runs-on: ubuntu-latest
16 | steps:
17 | - name: Checkout Repo
18 | uses: actions/checkout@master
19 | - name: Set Node.js 18.x
20 | uses: actions/setup-node@v3
21 | with:
22 | node-version: 18.x
23 | - name: Install Dependencies
24 | run: yarn install
25 | - name: Run tests
26 | run: yarn test
27 | - name: Run build test
28 | run: yarn run build-test
29 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .pnp.*
2 | .yarn/*
3 | !.yarn/patches
4 | !.yarn/plugins
5 | !.yarn/releases
6 | !.yarn/sdks
7 | !.yarn/versions
8 |
9 | **/node_modules
10 | **/package-lock.json
11 |
12 | # Swap the comments on the following lines if you don't wish to use zero-installs
13 | # Documentation here: https://yarnpkg.com/features/zero-installs
14 | .yarn/cache
15 | .pnp.*
16 | **/dist
17 | **/coverage
18 | totalsoft-rocket-ui-*.tgz
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | coverage
3 | tsconfig.json
4 | tsconfig.build.json
5 | .storybook
6 | .github
7 | __tests__
8 | __mocks__
9 | .babelrc
10 | eslint.config.mjs
11 | .gitignore
12 | .yarn
13 | .vscode
14 | .vim
15 | public
16 | .prettierrc
17 | src/testingUtils
18 | src/stories
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 125,
3 | "tabWidth": 2,
4 | "singleQuote": true,
5 | "semi": false,
6 | "trailingComma": "none",
7 | "arrowParens": "avoid"
8 | }
9 |
--------------------------------------------------------------------------------
/.storybook/DocsPage.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) TotalSoft.
2 | // This source code is licensed under the MIT license.
3 | import * as React from 'react'
4 | import { Controls, Description, DocsContext, Primary, Stories, Subtitle, Title } from '@storybook/blocks'
5 | import { makeStyles } from 'tss-react/mui'
6 | import { TableOfContent } from './TableOfContent'
7 |
8 | const useStyles = makeStyles()({
9 | wrapper: {
10 | display: 'flex'
11 | },
12 | toc: {
13 | flexBasis: '200px',
14 | flexShrink: 0,
15 | ['@media screen and (max-width: 1300px)']: {
16 | display: 'none'
17 | }
18 | },
19 | container: {
20 | width: '200px',
21 | flexGrow: 1
22 | }
23 | })
24 |
25 | export const DocsPage = () => {
26 | const context = React.useContext(DocsContext)
27 | const stories = context.componentStories()
28 | const { classes } = useStyles()
29 |
30 | return (
31 | <>
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
44 |
45 | >
46 | )
47 | }
48 |
--------------------------------------------------------------------------------
/.storybook/doc-root.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) TotalSoft.
3 | * This source code is licensed under the MIT license.
4 | */
5 | .sbdocs .sbdocs-content {
6 | max-width: 1300px;
7 | }
8 |
--------------------------------------------------------------------------------
/.storybook/main.ts:
--------------------------------------------------------------------------------
1 | import { dirname, join } from 'path'
2 | import type { StorybookConfig } from '@storybook/react-webpack5'
3 | import TsconfigPathsPlugin from 'tsconfig-paths-webpack-plugin'
4 |
5 | const config: StorybookConfig = {
6 | stories: ['../src/**/*.stories.@(js|jsx|ts|tsx)'],
7 | addons: [
8 | getAbsolutePath('@storybook/addon-essentials'),
9 | getAbsolutePath('@storybook/addon-links'),
10 | getAbsolutePath('@storybook/addon-interactions'),
11 | getAbsolutePath('@storybook/preview-api'),
12 | getAbsolutePath('@storybook/addon-webpack5-compiler-swc')
13 | ],
14 | staticDirs: ['../public'],
15 | framework: {
16 | name: getAbsolutePath('@storybook/react-webpack5'),
17 | options: {}
18 | },
19 | core: {
20 | builder: getAbsolutePath('@storybook/builder-webpack5')
21 | },
22 | typescript: {
23 | reactDocgen: 'react-docgen',
24 | check: false
25 | },
26 | webpackFinal: async (config: any) => {
27 | config.resolve.plugins = [new TsconfigPathsPlugin()]
28 | return config
29 | }
30 | }
31 | export default config
32 |
33 | function getAbsolutePath(value: string): any {
34 | return dirname(require.resolve(join(value, 'package.json')))
35 | }
36 |
--------------------------------------------------------------------------------
/.storybook/manager-head.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
--------------------------------------------------------------------------------
/.storybook/preview.tsx:
--------------------------------------------------------------------------------
1 | import './doc-root.css'
2 | import React from 'react'
3 | import type { Preview } from '@storybook/react'
4 | import { ThemeProvider } from '@mui/material/styles'
5 | import { ToastContainer } from '../src/components/feedback/Toast'
6 | import getTheme from '../src/components/themes/index'
7 | import { DocsPage } from './DocsPage'
8 |
9 | const withThemeProvider = (Story, context) => {
10 | const theme = getTheme(context)
11 | return (
12 |
13 |
14 |
15 |
16 | )
17 | }
18 |
19 | const preview: Preview = {
20 | parameters: {
21 | controls: {
22 | expanded: true
23 | },
24 | docs: {
25 | page: DocsPage,
26 | source: {
27 | language: 'tsx',
28 | excludeDecorators: true
29 | }
30 | }
31 | },
32 | globalTypes: {
33 | theme: {
34 | name: 'Theme',
35 | description: 'Global theme for components',
36 | defaultValue: 'default',
37 | toolbar: {
38 | icon: 'circlehollow',
39 | items: ['default', 'green', 'blue', 'orange', 'red', 'vividOrange', 'lightBlue'],
40 | title: 'Theme',
41 | dynamicTitle: true
42 | }
43 | }
44 | },
45 | decorators: [withThemeProvider],
46 | tags: ['autodocs']
47 | }
48 |
49 | export default preview
50 |
--------------------------------------------------------------------------------
/.vim/coc-settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "eslint.packageManager": "yarn",
3 | "eslint.nodePath": ".yarn/sdks",
4 | "workspace.workspaceFolderCheckCwd": false,
5 | "tsserver.tsdk": ".yarn/sdks/typescript/lib"
6 | }
7 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "arcanis.vscode-zipfs",
4 | "dbaeumer.vscode-eslint",
5 | "esbenp.prettier-vscode"
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "configurations": [
3 | {
4 | "name": "Storybook Debug",
5 | "type": "node-terminal",
6 | "request": "launch",
7 | "command": "yarn storybook",
8 | "internalConsoleOptions": "openOnFirstSessionStart",
9 | "serverReadyAction": {
10 | "pattern": "Local:.+(https?://[^:]+:[0-9]+)",
11 | "uriFormat": "%s",
12 | "action": "debugWithChrome"
13 | }
14 | },
15 | {
16 | "type": "node",
17 | "name": "vscode-jest-tests",
18 | "request": "launch",
19 | "runtimeExecutable": "yarn",
20 | "runtimeArgs": ["run", "test"],
21 | "args": ["--runInBand"],
22 | "cwd": "${workspaceFolder}",
23 | "console": "integratedTerminal",
24 | "internalConsoleOptions": "neverOpen"
25 | },
26 | {
27 | "type": "node",
28 | "name": "Jest current file",
29 | "request": "launch",
30 | "runtimeExecutable": "yarn",
31 | "runtimeArgs": ["run", "test"],
32 | "args": ["--verbose", "-i", "--no-cache", "--testPathPattern", "/${fileBasename}"],
33 | "cwd": "${fileDirname}",
34 | "console": "integratedTerminal",
35 | "internalConsoleOptions": "neverOpen"
36 | }
37 | ]
38 | }
39 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "search.exclude": {
3 | "**/.yarn": true,
4 | "**/.pnp.*": true
5 | },
6 | "prettier.prettierPath": ".yarn/sdks/prettier/index.cjs",
7 | "editor.defaultFormatter": "esbenp.prettier-vscode",
8 | "eslint.nodePath": ".yarn/sdks/eslint",
9 | "eslint.useFlatConfig": true,
10 | "typescript.tsdk": ".yarn/sdks/typescript/lib",
11 | "typescript.enablePromptUseWorkspaceTsdk": true,
12 | "typescript.updateImportsOnFileMove.enabled": "always",
13 | "typescript.tsserver.log": "verbose",
14 | "npm.packageManager": "yarn",
15 | "cSpell.words": [
16 | "autodocs",
17 | "commitish",
18 | "copyfiles",
19 | "rsbuild",
20 | "storybuild",
21 | "Toastify",
22 | "Totalsoft",
23 | "uuidv"
24 | ],
25 | "licenser.license": "Custom",
26 | "licenser.author": "TotalSoft",
27 | "licenser.customHeader": "Copyright (c) @AUTHOR@.\nThis source code is licensed under the MIT license."
28 | }
29 |
--------------------------------------------------------------------------------
/.yarn/sdks/eslint/bin/eslint.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const {existsSync} = require(`fs`);
4 | const {createRequire, register} = require(`module`);
5 | const {resolve} = require(`path`);
6 | const {pathToFileURL} = require(`url`);
7 |
8 | const relPnpApiPath = "../../../../.pnp.cjs";
9 |
10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath);
11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`);
12 | const absRequire = createRequire(absPnpApiPath);
13 |
14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`);
15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath);
16 |
17 | if (existsSync(absPnpApiPath)) {
18 | if (!process.versions.pnp) {
19 | // Setup the environment to be able to require eslint/bin/eslint.js
20 | require(absPnpApiPath).setup();
21 | if (isPnpLoaderEnabled && register) {
22 | register(pathToFileURL(absPnpLoaderPath));
23 | }
24 | }
25 | }
26 |
27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath)
28 | ? exports => absRequire(absUserWrapperPath)(exports)
29 | : exports => exports;
30 |
31 | // Defer to the real eslint/bin/eslint.js your application uses
32 | module.exports = wrapWithUserWrapper(absRequire(`eslint/bin/eslint.js`));
33 |
--------------------------------------------------------------------------------
/.yarn/sdks/eslint/lib/api.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const {existsSync} = require(`fs`);
4 | const {createRequire, register} = require(`module`);
5 | const {resolve} = require(`path`);
6 | const {pathToFileURL} = require(`url`);
7 |
8 | const relPnpApiPath = "../../../../.pnp.cjs";
9 |
10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath);
11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`);
12 | const absRequire = createRequire(absPnpApiPath);
13 |
14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`);
15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath);
16 |
17 | if (existsSync(absPnpApiPath)) {
18 | if (!process.versions.pnp) {
19 | // Setup the environment to be able to require eslint
20 | require(absPnpApiPath).setup();
21 | if (isPnpLoaderEnabled && register) {
22 | register(pathToFileURL(absPnpLoaderPath));
23 | }
24 | }
25 | }
26 |
27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath)
28 | ? exports => absRequire(absUserWrapperPath)(exports)
29 | : exports => exports;
30 |
31 | // Defer to the real eslint your application uses
32 | module.exports = wrapWithUserWrapper(absRequire(`eslint`));
33 |
--------------------------------------------------------------------------------
/.yarn/sdks/eslint/lib/types/index.d.ts:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const {existsSync} = require(`fs`);
4 | const {createRequire, register} = require(`module`);
5 | const {resolve} = require(`path`);
6 | const {pathToFileURL} = require(`url`);
7 |
8 | const relPnpApiPath = "../../../../../.pnp.cjs";
9 |
10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath);
11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`);
12 | const absRequire = createRequire(absPnpApiPath);
13 |
14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`);
15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath);
16 |
17 | if (existsSync(absPnpApiPath)) {
18 | if (!process.versions.pnp) {
19 | // Setup the environment to be able to require eslint
20 | require(absPnpApiPath).setup();
21 | if (isPnpLoaderEnabled && register) {
22 | register(pathToFileURL(absPnpLoaderPath));
23 | }
24 | }
25 | }
26 |
27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath)
28 | ? exports => absRequire(absUserWrapperPath)(exports)
29 | : exports => exports;
30 |
31 | // Defer to the real eslint your application uses
32 | module.exports = wrapWithUserWrapper(absRequire(`eslint`));
33 |
--------------------------------------------------------------------------------
/.yarn/sdks/eslint/lib/types/rules/index.d.ts:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const {existsSync} = require(`fs`);
4 | const {createRequire, register} = require(`module`);
5 | const {resolve} = require(`path`);
6 | const {pathToFileURL} = require(`url`);
7 |
8 | const relPnpApiPath = "../../../../../../.pnp.cjs";
9 |
10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath);
11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`);
12 | const absRequire = createRequire(absPnpApiPath);
13 |
14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`);
15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath);
16 |
17 | if (existsSync(absPnpApiPath)) {
18 | if (!process.versions.pnp) {
19 | // Setup the environment to be able to require eslint/rules
20 | require(absPnpApiPath).setup();
21 | if (isPnpLoaderEnabled && register) {
22 | register(pathToFileURL(absPnpLoaderPath));
23 | }
24 | }
25 | }
26 |
27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath)
28 | ? exports => absRequire(absUserWrapperPath)(exports)
29 | : exports => exports;
30 |
31 | // Defer to the real eslint/rules your application uses
32 | module.exports = wrapWithUserWrapper(absRequire(`eslint/rules`));
33 |
--------------------------------------------------------------------------------
/.yarn/sdks/eslint/lib/types/universal.d.ts:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const {existsSync} = require(`fs`);
4 | const {createRequire, register} = require(`module`);
5 | const {resolve} = require(`path`);
6 | const {pathToFileURL} = require(`url`);
7 |
8 | const relPnpApiPath = "../../../../../.pnp.cjs";
9 |
10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath);
11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`);
12 | const absRequire = createRequire(absPnpApiPath);
13 |
14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`);
15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath);
16 |
17 | if (existsSync(absPnpApiPath)) {
18 | if (!process.versions.pnp) {
19 | // Setup the environment to be able to require eslint/universal
20 | require(absPnpApiPath).setup();
21 | if (isPnpLoaderEnabled && register) {
22 | register(pathToFileURL(absPnpLoaderPath));
23 | }
24 | }
25 | }
26 |
27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath)
28 | ? exports => absRequire(absUserWrapperPath)(exports)
29 | : exports => exports;
30 |
31 | // Defer to the real eslint/universal your application uses
32 | module.exports = wrapWithUserWrapper(absRequire(`eslint/universal`));
33 |
--------------------------------------------------------------------------------
/.yarn/sdks/eslint/lib/types/use-at-your-own-risk.d.ts:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const {existsSync} = require(`fs`);
4 | const {createRequire, register} = require(`module`);
5 | const {resolve} = require(`path`);
6 | const {pathToFileURL} = require(`url`);
7 |
8 | const relPnpApiPath = "../../../../../.pnp.cjs";
9 |
10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath);
11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`);
12 | const absRequire = createRequire(absPnpApiPath);
13 |
14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`);
15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath);
16 |
17 | if (existsSync(absPnpApiPath)) {
18 | if (!process.versions.pnp) {
19 | // Setup the environment to be able to require eslint/use-at-your-own-risk
20 | require(absPnpApiPath).setup();
21 | if (isPnpLoaderEnabled && register) {
22 | register(pathToFileURL(absPnpLoaderPath));
23 | }
24 | }
25 | }
26 |
27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath)
28 | ? exports => absRequire(absUserWrapperPath)(exports)
29 | : exports => exports;
30 |
31 | // Defer to the real eslint/use-at-your-own-risk your application uses
32 | module.exports = wrapWithUserWrapper(absRequire(`eslint/use-at-your-own-risk`));
33 |
--------------------------------------------------------------------------------
/.yarn/sdks/eslint/lib/universal.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const {existsSync} = require(`fs`);
4 | const {createRequire, register} = require(`module`);
5 | const {resolve} = require(`path`);
6 | const {pathToFileURL} = require(`url`);
7 |
8 | const relPnpApiPath = "../../../../.pnp.cjs";
9 |
10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath);
11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`);
12 | const absRequire = createRequire(absPnpApiPath);
13 |
14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`);
15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath);
16 |
17 | if (existsSync(absPnpApiPath)) {
18 | if (!process.versions.pnp) {
19 | // Setup the environment to be able to require eslint/universal
20 | require(absPnpApiPath).setup();
21 | if (isPnpLoaderEnabled && register) {
22 | register(pathToFileURL(absPnpLoaderPath));
23 | }
24 | }
25 | }
26 |
27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath)
28 | ? exports => absRequire(absUserWrapperPath)(exports)
29 | : exports => exports;
30 |
31 | // Defer to the real eslint/universal your application uses
32 | module.exports = wrapWithUserWrapper(absRequire(`eslint/universal`));
33 |
--------------------------------------------------------------------------------
/.yarn/sdks/eslint/lib/unsupported-api.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const {existsSync} = require(`fs`);
4 | const {createRequire, register} = require(`module`);
5 | const {resolve} = require(`path`);
6 | const {pathToFileURL} = require(`url`);
7 |
8 | const relPnpApiPath = "../../../../.pnp.cjs";
9 |
10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath);
11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`);
12 | const absRequire = createRequire(absPnpApiPath);
13 |
14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`);
15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath);
16 |
17 | if (existsSync(absPnpApiPath)) {
18 | if (!process.versions.pnp) {
19 | // Setup the environment to be able to require eslint/use-at-your-own-risk
20 | require(absPnpApiPath).setup();
21 | if (isPnpLoaderEnabled && register) {
22 | register(pathToFileURL(absPnpLoaderPath));
23 | }
24 | }
25 | }
26 |
27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath)
28 | ? exports => absRequire(absUserWrapperPath)(exports)
29 | : exports => exports;
30 |
31 | // Defer to the real eslint/use-at-your-own-risk your application uses
32 | module.exports = wrapWithUserWrapper(absRequire(`eslint/use-at-your-own-risk`));
33 |
--------------------------------------------------------------------------------
/.yarn/sdks/eslint/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "eslint",
3 | "version": "9.14.0-sdk",
4 | "main": "./lib/api.js",
5 | "type": "commonjs",
6 | "bin": {
7 | "eslint": "./bin/eslint.js"
8 | },
9 | "exports": {
10 | ".": {
11 | "types": "./lib/types/index.d.ts",
12 | "default": "./lib/api.js"
13 | },
14 | "./package.json": "./package.json",
15 | "./use-at-your-own-risk": {
16 | "types": "./lib/types/use-at-your-own-risk.d.ts",
17 | "default": "./lib/unsupported-api.js"
18 | },
19 | "./rules": {
20 | "types": "./lib/types/rules/index.d.ts"
21 | },
22 | "./universal": {
23 | "types": "./lib/types/universal.d.ts",
24 | "default": "./lib/universal.js"
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/.yarn/sdks/integrations.yml:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by @yarnpkg/sdks.
2 | # Manual changes might be lost!
3 |
4 | integrations:
5 | - vim
6 | - vscode
7 |
--------------------------------------------------------------------------------
/.yarn/sdks/prettier/bin/prettier.cjs:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const {existsSync} = require(`fs`);
4 | const {createRequire, register} = require(`module`);
5 | const {resolve} = require(`path`);
6 | const {pathToFileURL} = require(`url`);
7 |
8 | const relPnpApiPath = "../../../../.pnp.cjs";
9 |
10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath);
11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`);
12 | const absRequire = createRequire(absPnpApiPath);
13 |
14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`);
15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath);
16 |
17 | if (existsSync(absPnpApiPath)) {
18 | if (!process.versions.pnp) {
19 | // Setup the environment to be able to require prettier/bin/prettier.cjs
20 | require(absPnpApiPath).setup();
21 | if (isPnpLoaderEnabled && register) {
22 | register(pathToFileURL(absPnpLoaderPath));
23 | }
24 | }
25 | }
26 |
27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath)
28 | ? exports => absRequire(absUserWrapperPath)(exports)
29 | : exports => exports;
30 |
31 | // Defer to the real prettier/bin/prettier.cjs your application uses
32 | module.exports = wrapWithUserWrapper(absRequire(`prettier/bin/prettier.cjs`));
33 |
--------------------------------------------------------------------------------
/.yarn/sdks/prettier/index.cjs:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const {existsSync} = require(`fs`);
4 | const {createRequire, register} = require(`module`);
5 | const {resolve} = require(`path`);
6 | const {pathToFileURL} = require(`url`);
7 |
8 | const relPnpApiPath = "../../../.pnp.cjs";
9 |
10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath);
11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`);
12 | const absRequire = createRequire(absPnpApiPath);
13 |
14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`);
15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath);
16 |
17 | if (existsSync(absPnpApiPath)) {
18 | if (!process.versions.pnp) {
19 | // Setup the environment to be able to require prettier
20 | require(absPnpApiPath).setup();
21 | if (isPnpLoaderEnabled && register) {
22 | register(pathToFileURL(absPnpLoaderPath));
23 | }
24 | }
25 | }
26 |
27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath)
28 | ? exports => absRequire(absUserWrapperPath)(exports)
29 | : exports => exports;
30 |
31 | // Defer to the real prettier your application uses
32 | module.exports = wrapWithUserWrapper(absRequire(`prettier`));
33 |
--------------------------------------------------------------------------------
/.yarn/sdks/prettier/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "prettier",
3 | "version": "3.3.3-sdk",
4 | "main": "./index.cjs",
5 | "type": "commonjs",
6 | "bin": "./bin/prettier.cjs"
7 | }
8 |
--------------------------------------------------------------------------------
/.yarn/sdks/typescript/bin/tsc:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const {existsSync} = require(`fs`);
4 | const {createRequire, register} = require(`module`);
5 | const {resolve} = require(`path`);
6 | const {pathToFileURL} = require(`url`);
7 |
8 | const relPnpApiPath = "../../../../.pnp.cjs";
9 |
10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath);
11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`);
12 | const absRequire = createRequire(absPnpApiPath);
13 |
14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`);
15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath);
16 |
17 | if (existsSync(absPnpApiPath)) {
18 | if (!process.versions.pnp) {
19 | // Setup the environment to be able to require typescript/bin/tsc
20 | require(absPnpApiPath).setup();
21 | if (isPnpLoaderEnabled && register) {
22 | register(pathToFileURL(absPnpLoaderPath));
23 | }
24 | }
25 | }
26 |
27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath)
28 | ? exports => absRequire(absUserWrapperPath)(exports)
29 | : exports => exports;
30 |
31 | // Defer to the real typescript/bin/tsc your application uses
32 | module.exports = wrapWithUserWrapper(absRequire(`typescript/bin/tsc`));
33 |
--------------------------------------------------------------------------------
/.yarn/sdks/typescript/bin/tsserver:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const {existsSync} = require(`fs`);
4 | const {createRequire, register} = require(`module`);
5 | const {resolve} = require(`path`);
6 | const {pathToFileURL} = require(`url`);
7 |
8 | const relPnpApiPath = "../../../../.pnp.cjs";
9 |
10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath);
11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`);
12 | const absRequire = createRequire(absPnpApiPath);
13 |
14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`);
15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath);
16 |
17 | if (existsSync(absPnpApiPath)) {
18 | if (!process.versions.pnp) {
19 | // Setup the environment to be able to require typescript/bin/tsserver
20 | require(absPnpApiPath).setup();
21 | if (isPnpLoaderEnabled && register) {
22 | register(pathToFileURL(absPnpLoaderPath));
23 | }
24 | }
25 | }
26 |
27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath)
28 | ? exports => absRequire(absUserWrapperPath)(exports)
29 | : exports => exports;
30 |
31 | // Defer to the real typescript/bin/tsserver your application uses
32 | module.exports = wrapWithUserWrapper(absRequire(`typescript/bin/tsserver`));
33 |
--------------------------------------------------------------------------------
/.yarn/sdks/typescript/lib/tsc.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const {existsSync} = require(`fs`);
4 | const {createRequire, register} = require(`module`);
5 | const {resolve} = require(`path`);
6 | const {pathToFileURL} = require(`url`);
7 |
8 | const relPnpApiPath = "../../../../.pnp.cjs";
9 |
10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath);
11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`);
12 | const absRequire = createRequire(absPnpApiPath);
13 |
14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`);
15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath);
16 |
17 | if (existsSync(absPnpApiPath)) {
18 | if (!process.versions.pnp) {
19 | // Setup the environment to be able to require typescript/lib/tsc.js
20 | require(absPnpApiPath).setup();
21 | if (isPnpLoaderEnabled && register) {
22 | register(pathToFileURL(absPnpLoaderPath));
23 | }
24 | }
25 | }
26 |
27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath)
28 | ? exports => absRequire(absUserWrapperPath)(exports)
29 | : exports => exports;
30 |
31 | // Defer to the real typescript/lib/tsc.js your application uses
32 | module.exports = wrapWithUserWrapper(absRequire(`typescript/lib/tsc.js`));
33 |
--------------------------------------------------------------------------------
/.yarn/sdks/typescript/lib/typescript.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const {existsSync} = require(`fs`);
4 | const {createRequire, register} = require(`module`);
5 | const {resolve} = require(`path`);
6 | const {pathToFileURL} = require(`url`);
7 |
8 | const relPnpApiPath = "../../../../.pnp.cjs";
9 |
10 | const absPnpApiPath = resolve(__dirname, relPnpApiPath);
11 | const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`);
12 | const absRequire = createRequire(absPnpApiPath);
13 |
14 | const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`);
15 | const isPnpLoaderEnabled = existsSync(absPnpLoaderPath);
16 |
17 | if (existsSync(absPnpApiPath)) {
18 | if (!process.versions.pnp) {
19 | // Setup the environment to be able to require typescript
20 | require(absPnpApiPath).setup();
21 | if (isPnpLoaderEnabled && register) {
22 | register(pathToFileURL(absPnpLoaderPath));
23 | }
24 | }
25 | }
26 |
27 | const wrapWithUserWrapper = existsSync(absUserWrapperPath)
28 | ? exports => absRequire(absUserWrapperPath)(exports)
29 | : exports => exports;
30 |
31 | // Defer to the real typescript your application uses
32 | module.exports = wrapWithUserWrapper(absRequire(`typescript`));
33 |
--------------------------------------------------------------------------------
/.yarn/sdks/typescript/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "typescript",
3 | "version": "5.6.3-sdk",
4 | "main": "./lib/typescript.js",
5 | "type": "commonjs",
6 | "bin": {
7 | "tsc": "./bin/tsc",
8 | "tsserver": "./bin/tsserver"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/.yarn/versions/9085f262.yml:
--------------------------------------------------------------------------------
1 | # Copyright (c) TotalSoft.
2 | # This source code is licensed under the MIT license.
3 |
4 |
--------------------------------------------------------------------------------
/.yarnrc.yml:
--------------------------------------------------------------------------------
1 | yarnPath: .yarn/releases/yarn-4.5.1.cjs
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 osstotalsoft
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 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/osstotalsoft/rocket-ui-ts/80feca8180b7ce5d2767a81eaa53475aab999793/public/favicon.ico
--------------------------------------------------------------------------------
/public/faviconGlobe.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/osstotalsoft/rocket-ui-ts/80feca8180b7ce5d2767a81eaa53475aab999793/public/faviconGlobe.ico
--------------------------------------------------------------------------------
/public/faviconReact.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/osstotalsoft/rocket-ui-ts/80feca8180b7ce5d2767a81eaa53475aab999793/public/faviconReact.ico
--------------------------------------------------------------------------------
/public/faviconTS.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/osstotalsoft/rocket-ui-ts/80feca8180b7ce5d2767a81eaa53475aab999793/public/faviconTS.ico
--------------------------------------------------------------------------------
/src/__mocks__/fileMock.js:
--------------------------------------------------------------------------------
1 | // Copyright (c) TotalSoft.
2 | // This source code is licensed under the MIT license.
3 |
4 |
--------------------------------------------------------------------------------
/src/components/assets/img/forbidden.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/osstotalsoft/rocket-ui-ts/80feca8180b7ce5d2767a81eaa53475aab999793/src/components/assets/img/forbidden.png
--------------------------------------------------------------------------------
/src/components/assets/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/osstotalsoft/rocket-ui-ts/80feca8180b7ce5d2767a81eaa53475aab999793/src/components/assets/img/logo.png
--------------------------------------------------------------------------------
/src/components/assets/img/miniLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/osstotalsoft/rocket-ui-ts/80feca8180b7ce5d2767a81eaa53475aab999793/src/components/assets/img/miniLogo.png
--------------------------------------------------------------------------------
/src/components/assets/img/notFound.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/osstotalsoft/rocket-ui-ts/80feca8180b7ce5d2767a81eaa53475aab999793/src/components/assets/img/notFound.png
--------------------------------------------------------------------------------
/src/components/buttons/BackToButton/BackToButton.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { BrowserRouter, Route, Routes } from 'react-router'
3 | import BackToButton from './BackToButton'
4 | import { render, userClick, waitFor, screen, act } from '../../../testingUtils'
5 |
6 | describe('BackToButton', () => {
7 | test('redirects to the path received', async () => {
8 | render(
9 |
10 |
11 |
12 | {'redirected'}}>
13 |
14 |
15 | )
16 | act(() => userClick(screen.getByRole('button')))
17 | await waitFor(() => {
18 | expect(screen.getByText('redirected')).toBeInTheDocument()
19 | })
20 | })
21 | })
22 |
--------------------------------------------------------------------------------
/src/components/buttons/BackToButton/index.ts:
--------------------------------------------------------------------------------
1 | export * from './types'
2 | import BackToButton from './BackToButton'
3 | export default BackToButton
4 |
--------------------------------------------------------------------------------
/src/components/buttons/BackToButton/types.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) TotalSoft.
2 | // This source code is licensed under the MIT license.
3 |
4 | import { NavigateOptions } from 'react-router'
5 | import { IconButtonProps } from '../IconButton/types'
6 |
7 | export interface BackToButtonProps extends Omit {
8 | /**
9 | * Path where browser will be directed to when the button is clicked.
10 | */
11 | path: string | number
12 | /**
13 | * Navigation options.
14 | * flushSync?: boolean;
15 | * preventScrollReset?: boolean;
16 | * relative?: RelativeRoutingType;
17 | * replace?: boolean;
18 | * state?: any;
19 | * viewTransition?: boolean;
20 | */
21 | options?: NavigateOptions
22 | }
23 |
--------------------------------------------------------------------------------
/src/components/buttons/Button/index.ts:
--------------------------------------------------------------------------------
1 | export * from './types'
2 | import Button from './Button'
3 | export default Button
4 |
--------------------------------------------------------------------------------
/src/components/buttons/Button/types.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) TotalSoft.
2 | // This source code is licensed under the MIT license.
3 | import { ButtonProps as MuiButtonProps } from '@mui/material'
4 | import { Color, Size } from '../../types'
5 |
6 | export type ButtonVariant = 'outlined' | 'text' | 'contained'
7 |
8 | export interface ButtonProps extends Omit {
9 | variant?: ButtonVariant
10 | /**
11 | * The color of the button.
12 | */
13 | color?: Color
14 | /**
15 | * The size of the button.
16 | */
17 | size?: Size
18 | /**
19 | * The tooltip of the button.
20 | */
21 | tooltip?: string
22 | /**
23 | * If true, rounded corners are enabled.
24 | */
25 | round?: boolean
26 | /**
27 | * If true, the button will float to the right.
28 | */
29 | right?: boolean
30 | /**
31 | * If true, the button will be smaller.
32 | */
33 | justIcon?: boolean
34 | /**
35 | * If true, button is in loading state.
36 | */
37 | loading?: boolean
38 | /**
39 | * If true, the button's min width will be set to 160px.
40 | */
41 | wd?: boolean
42 | /**
43 | * If true, a gradient background is applied.
44 | */
45 | gradient?: boolean
46 | /**
47 | * @default true
48 | * If true, button text is capitalized.
49 | */
50 | capitalize?: boolean
51 | /**
52 | * Used for upload
53 | */
54 | component?: string
55 | }
56 |
--------------------------------------------------------------------------------
/src/components/buttons/IconButton/IconButtonStyles.ts:
--------------------------------------------------------------------------------
1 | import { styled } from '@mui/material/styles'
2 | import Button from '../Button'
3 |
4 | const IconButton = styled(Button)(() => ({
5 | alignItems: 'center',
6 | justifyContent: 'center',
7 | position: 'relative',
8 | display: 'inline-flex',
9 | borderRadius: '50%',
10 | minWidth: '0px',
11 | '&.MuiButton-sizeSmall': {
12 | padding: '0px',
13 | width: '40px',
14 | height: '40px'
15 | },
16 | '&.MuiButton-sizeMedium': {
17 | padding: '11px',
18 | width: '48px',
19 | height: '48px'
20 | },
21 | '&.MuiButton-sizeLarge': {
22 | padding: '15px',
23 | width: '52px',
24 | height: '52px'
25 | }
26 | }))
27 |
28 | export default IconButton
29 |
--------------------------------------------------------------------------------
/src/components/buttons/IconButton/index.ts:
--------------------------------------------------------------------------------
1 | export * from './types'
2 | import IconButton from './IconButton'
3 | export default IconButton
4 |
--------------------------------------------------------------------------------
/src/components/buttons/UploadButton/index.ts:
--------------------------------------------------------------------------------
1 | export * from './types'
2 | import UploadButton from './UploadButton'
3 | export default UploadButton
4 |
--------------------------------------------------------------------------------
/src/components/charts/DeprecatedChart/index.ts:
--------------------------------------------------------------------------------
1 | export * from './types'
2 | import DeprecatedChart from './DeprecatedChart'
3 | export default DeprecatedChart
4 |
--------------------------------------------------------------------------------
/src/components/charts/DeprecatedChart/types.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) TotalSoft.
2 | // This source code is licensed under the MIT license.
3 |
4 | import { SvgIconComponent } from '@mui/icons-material'
5 | import { CardProps } from '../..'
6 | import { ChartProps } from 'react-chartjs-2'
7 |
8 | export interface DeprecatedChartProps extends Omit {
9 | /**
10 | * Chart subtitle.
11 | */
12 | subheader?: React.ReactNode
13 | /**
14 | * Chart icon.
15 | */
16 | Icon?: SvgIconComponent
17 | /**
18 | * Chart icon color.
19 | */
20 | iconColor?: string
21 | /**
22 | * Content of the title.
23 | */
24 | title?: React.ReactNode
25 | cardProps?: CardProps
26 | }
27 |
--------------------------------------------------------------------------------
/src/components/charts/DeprecatedStatsChart/index.ts:
--------------------------------------------------------------------------------
1 | export * from './types'
2 | import DeprecatedStatsChart from './DeprecatedStatsChart'
3 | export default DeprecatedStatsChart
4 |
--------------------------------------------------------------------------------
/src/components/charts/DeprecatedStatsChart/types.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) TotalSoft.
2 | // This source code is licensed under the MIT license.
3 |
4 | import { SvgIconComponent } from '@mui/icons-material'
5 | import { ChartProps } from 'react-chartjs-2'
6 | import { Color } from '../../types'
7 |
8 | export interface DataSetsChart {
9 | data: number[]
10 | label: string
11 | backgroundColor: string
12 | borderColor: string
13 | }
14 |
15 | export type DeprecatedStatsIconColor = Exclude
16 |
17 | export interface DeprecatedStatsChartProps extends Omit {
18 | /**
19 | * Chart type.
20 | */
21 | type?: 'line' | 'bar'
22 | /**
23 | * The text content of chart.
24 | */
25 | text?: string
26 | /**
27 | * Chart icon.
28 | */
29 | StatIcon?: SvgIconComponent
30 | /**
31 | * @default 'grey'
32 | * Chart icon color.
33 | */
34 | iconColor?: DeprecatedStatsIconColor
35 | /**
36 | * @default 'info'
37 | * Chart color.
38 | */
39 | chartColor?: Color
40 | /**
41 | * Chart status text.
42 | */
43 | statText?: React.ReactNode
44 | /**
45 | * Chart data.
46 | */
47 | data: {
48 | labels: string[]
49 | datasets: DataSetsChart[]
50 | }
51 | /**
52 | * Action to be displayed in the right corner of the card.
53 | */
54 | statAction?: React.ReactNode
55 | }
56 |
--------------------------------------------------------------------------------
/src/components/dataDisplay/ExpandingText/ExpandingTextStyles.ts:
--------------------------------------------------------------------------------
1 | import { styled } from '@mui/material/styles'
2 | import Typography from '../Typography'
3 |
4 | const ExpandAction = styled(Typography)(({ theme }) => ({
5 | color: theme?.palette.link.main,
6 | cursor: 'pointer'
7 | }))
8 |
9 | export default ExpandAction
10 |
--------------------------------------------------------------------------------
/src/components/dataDisplay/ExpandingText/index.ts:
--------------------------------------------------------------------------------
1 | export * from './types'
2 | import ExpandingText from './ExpandingText'
3 | export default ExpandingText
4 |
--------------------------------------------------------------------------------
/src/components/dataDisplay/ExpandingText/types.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) TotalSoft.
2 | // This source code is licensed under the MIT license.
3 |
4 | import { TypographyProps } from '../Typography/types'
5 |
6 | export type DisplayType = 'inline' | 'block' | 'inline-block' | 'flex' | 'inline-flex' | 'none'
7 |
8 | export interface ExpandingTextProps extends TypographyProps {
9 | /**
10 | * Text to be displayed.
11 | */
12 | text: string
13 | /**
14 | * Length of text to be displayed.
15 | */
16 | minLength?: number
17 | /**
18 | * @default 'Show less'
19 | * Text of `showLess` button.
20 | */
21 | showLessText?: React.ReactNode
22 | /**
23 | * @default 'Show more'
24 | * Text of `showMore` button.
25 | */
26 | showMoreText?: React.ReactNode
27 | /**
28 | * @default 'block'
29 | * CSS `display` prop applied to the text.
30 | */
31 | display?: DisplayType
32 | /**
33 | * Props applied to the text.
34 | */
35 | textProps?: TypographyProps
36 | /**
37 | * Props applied to the ShowLess/ShowMore component.
38 | */
39 | expandingActionProps?: TypographyProps
40 | /**
41 | * @default false
42 | * Expanded state of the text.
43 | */
44 | expanded?: boolean
45 | }
46 |
--------------------------------------------------------------------------------
/src/components/dataDisplay/FavIcon/FavIcon.tsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useCallback } from 'react'
2 | import PropTypes from 'prop-types'
3 | import { FavIconProps } from './types'
4 | import { is } from 'ramda'
5 | /**
6 | * The FavIcon component sets the favicon displayed by the browser on the website's tab
7 | * The html of the icon must have an id attribute of 'favicon'
8 | */
9 | const FavIcon: React.FC = ({ favIconSource, defaultFavIcon }) => {
10 | const onError = useCallback(
11 | (event: string | Event, favicon: HTMLLinkElement) => {
12 | favicon.href = defaultFavIcon || '#'
13 | if (is(String, event)) return
14 | const target = event.target as HTMLImageElement
15 | target.onerror = null
16 | },
17 | [defaultFavIcon]
18 | )
19 |
20 | const setFavIcon = useCallback(
21 | (source: string) => {
22 | const favicon = document.getElementById('favicon') as HTMLLinkElement || top.document.getElementById('favicon') as HTMLLinkElement
23 | const img = new Image()
24 | img.onerror = (event: string | Event) => onError(event, favicon)
25 | img.onload = () => (favicon.href = source || '#')
26 | img.src = source
27 | },
28 | [onError]
29 | )
30 |
31 | useEffect(() => {
32 | setFavIcon(favIconSource)
33 | }, [favIconSource, setFavIcon])
34 |
35 | return <>>
36 | }
37 |
38 | FavIcon.propTypes = {
39 | /**
40 | * URL of the favicon image
41 | */
42 | favIconSource: PropTypes.string,
43 | /**
44 | * URL of the fallback image. This will be used when the onerror event occurs
45 | */
46 | defaultFavIcon: PropTypes.string
47 | }
48 |
49 | export default FavIcon
50 |
--------------------------------------------------------------------------------
/src/components/dataDisplay/FavIcon/index.ts:
--------------------------------------------------------------------------------
1 | export * from './types'
2 | import FavIcon from './FavIcon'
3 | export default FavIcon
4 |
--------------------------------------------------------------------------------
/src/components/dataDisplay/FavIcon/types.ts:
--------------------------------------------------------------------------------
1 | export interface FavIconProps {
2 | /**
3 | * Path to the image
4 | */
5 | favIconSource?: string
6 | /**
7 | * Path to the fallback image. This will be used when the onerror event occurs
8 | */
9 | defaultFavIcon?: string
10 | }
--------------------------------------------------------------------------------
/src/components/dataDisplay/StatsChart/Chart.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import {
3 | BarChart,
4 | BarChartProps,
5 | Gauge,
6 | GaugeContainerProps,
7 | LineChart,
8 | LineChartProps,
9 | PieChart,
10 | PieChartProps,
11 | ScatterChart,
12 | ScatterChartProps
13 | } from '@mui/x-charts'
14 | import { ChartProps } from './types'
15 |
16 | /**
17 | * The Chart component serves as a unified interface for rendering all available chart types in MUI X,
18 | * providing flexibility and simplicity in chart selection.
19 | */
20 | const Chart: React.FC = ({ type, ...props }) => {
21 | switch (type) {
22 | case 'line':
23 | return
24 | case 'bar':
25 | return
26 | case 'pie':
27 | return
28 | case 'scatter':
29 | return
30 | case 'gauge':
31 | return
32 | default:
33 | return Unsupported chart type
34 | }
35 | }
36 |
37 | export default Chart
38 |
--------------------------------------------------------------------------------
/src/components/dataDisplay/StatsChart/StatsChart.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { render, screen } from '../../../testingUtils'
3 | import StatsChart from './StatsChart'
4 | import {
5 | barChartOptions,
6 | gaugeChartOptions,
7 | lineChartOptions,
8 | pieChartOptions,
9 | scatterChartOptions
10 | } from 'components/surfaces/StatsCard/_mocks'
11 | import { ChartProps } from './types'
12 |
13 | type ChartOption = {
14 | chartOptions: ChartProps
15 | testId: string
16 | text: string
17 | }
18 | const chartOptionsArray: ChartOption[] = [
19 | {
20 | chartOptions: { type: 'line', ...lineChartOptions },
21 | testId: 'line-chart',
22 | text: 'This is a line chart'
23 | },
24 | {
25 | chartOptions: { type: 'bar', ...barChartOptions },
26 | testId: 'bar-chart',
27 | text: 'This is a bar chart'
28 | },
29 | {
30 | chartOptions: { type: 'pie', ...pieChartOptions },
31 | testId: 'pie-chart',
32 | text: 'This is a pie chart'
33 | },
34 | {
35 | chartOptions: { type: 'scatter', ...scatterChartOptions },
36 | testId: 'scatter-chart',
37 | text: 'This is a scatter chart'
38 | },
39 | {
40 | chartOptions: { type: 'gauge', ...gaugeChartOptions },
41 | testId: 'gauge-chart',
42 | text: 'This is a gauge chart'
43 | }
44 | ]
45 |
46 | describe('Stats Chart tests', () => {
47 | it.each(chartOptionsArray)('renders the correct type of chart', ({ text, chartOptions, testId }) => {
48 | // arrange
49 | render()
50 | // act
51 | const element = screen.getByTestId(testId)
52 | // assert
53 | expect(element).toBeInTheDocument()
54 | })
55 | })
56 |
--------------------------------------------------------------------------------
/src/components/dataDisplay/StatsChart/index.ts:
--------------------------------------------------------------------------------
1 | export * from './types'
2 | import StatsChart from './StatsChart'
3 | export default StatsChart
4 |
--------------------------------------------------------------------------------
/src/components/dataDisplay/StatsChart/types.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) TotalSoft.
2 | // This source code is licensed under the MIT license.
3 |
4 | import { SvgIconComponent } from '@mui/icons-material'
5 |
6 | import { BarChartProps, GaugeContainerProps, LineChartProps, PieChartProps, ScatterChartProps } from '@mui/x-charts'
7 | import { Color } from 'components/types'
8 |
9 | //ChartType defines the chart types that can be used with the Chart component.
10 | export type ChartType = 'line' | 'bar' | 'pie' | 'scatter' | 'gauge'
11 |
12 | //ChartProps defines a discriminated union for handling multiple chart types.
13 | export type ChartProps =
14 | | ({ type: 'line' } & LineChartProps)
15 | | ({ type: 'bar' } & BarChartProps)
16 | | ({ type: 'pie' } & PieChartProps)
17 | | ({ type: 'scatter' } & ScatterChartProps)
18 | | ({ type: 'gauge' } & GaugeContainerProps)
19 |
20 | export type StatsChartProps = {
21 | chartColor?: Color
22 | iconColor?: StatsIconColor
23 | title: string
24 | text: string
25 | StatIcon?: SvgIconComponent
26 | statText?: string
27 | statAction?: React.ReactNode
28 | chart: ChartProps
29 | }
30 |
31 | export type StatsIconColor = Exclude
32 |
--------------------------------------------------------------------------------
/src/components/dataDisplay/Typography/TypographyStyles.ts:
--------------------------------------------------------------------------------
1 | import BaseTypography from '@mui/material/Typography'
2 | import { styled } from '@mui/material/styles'
3 | import { includes } from 'ramda'
4 |
5 | const Typography = styled(BaseTypography)(({ theme, variant }) => ({
6 | fontFamily: theme.typography.fontFamily,
7 | textTransform: includes(variant, ['overline', 'button']) ? 'uppercase' : 'none'
8 | }))
9 |
10 | export default Typography
11 |
--------------------------------------------------------------------------------
/src/components/dataDisplay/Typography/index.ts:
--------------------------------------------------------------------------------
1 | export * from './types'
2 | import Typography from './Typography'
3 | export default Typography
4 |
--------------------------------------------------------------------------------
/src/components/dataDisplay/Typography/types.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) TotalSoft.
2 | // This source code is licensed under the MIT license.
3 | import { TypographyProps as MuiTypographyProps } from '@mui/material'
4 |
5 | /**
6 | * The color of the text.
7 | */
8 | export type TypographyColor =
9 | | 'initial'
10 | | 'inherit'
11 | | 'primary'
12 | | 'secondary'
13 | | 'textPrimary'
14 | | 'textSecondary'
15 | | 'error'
16 | | string
17 |
18 | /**
19 | * Controls the text emphasis. Different font styles can be used individually or in combination.
20 | */
21 | export type Emphasis = 'bold' | 'italic' | 'underline' | 'line-through' | 'overline'
22 |
23 | export interface TypographyProps extends MuiTypographyProps {
24 | /**
25 | * The color of the text
26 | */
27 | color?: TypographyColor
28 | /**
29 | * If provided, a text will appear on hover.
30 | */
31 | tooltip?: React.ReactNode
32 | /**
33 | * Controls the text emphasis. Different font styles can be used individually or in combination
34 | */
35 | emphasis?: Emphasis | Emphasis[]
36 | }
37 |
--------------------------------------------------------------------------------
/src/components/feedback/Dialog/DialogStyles.ts:
--------------------------------------------------------------------------------
1 | import MuiDialogContent from '@mui/material/DialogContent'
2 | import MuiDialogTitle from '@mui/material/DialogTitle'
3 | import Backdrop from '@mui/material/Backdrop'
4 | import { styled } from '@mui/material/styles'
5 |
6 | export const justifyRight = {
7 | position: 'absolute',
8 | top: 'auto',
9 | right: 14
10 | }
11 |
12 | export const DialogContent = styled(MuiDialogContent)(({ theme }) => ({
13 | fontFamily: theme.typography.defaultFont.fontFamily,
14 | fontSize: theme.typography.defaultFont.fontSize
15 | }))
16 |
17 | export const DialogTitle = styled(MuiDialogTitle)(({ theme }) => ({
18 | fontFamily: theme.typography.defaultFont.fontFamily,
19 | padding: 0
20 | }))
21 |
22 | export const TransparentBackdrop = styled(Backdrop)(() => ({
23 | backgroundColor: 'transparent'
24 | }))
25 |
--------------------------------------------------------------------------------
/src/components/feedback/Dialog/index.ts:
--------------------------------------------------------------------------------
1 | import Dialog from './Dialog'
2 | export default Dialog
3 | export * from './types'
4 |
--------------------------------------------------------------------------------
/src/components/feedback/FakeText/index.ts:
--------------------------------------------------------------------------------
1 | export * from './types'
2 | import FakeText from './FakeText'
3 | export default FakeText
4 |
--------------------------------------------------------------------------------
/src/components/feedback/FakeText/types.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) TotalSoft.
2 | // This source code is licensed under the MIT license.
3 | import { SkeletonProps } from '@mui/material/Skeleton'
4 |
5 | export interface FakeTextProps extends Omit {
6 | /**
7 | * @default 'wave'
8 | * The animation. If false, the animation effect is disabled
9 | */
10 | animation?: 'pulse' | 'wave' | false
11 | /**
12 | * @default 1
13 | * The number of fake line texts that will be rendered
14 | */
15 | lines?: number
16 | /**
17 | * @default false
18 | * If set to true, the fake text will render on a Paper component
19 | */
20 | onPaper?: boolean
21 | }
22 |
--------------------------------------------------------------------------------
/src/components/feedback/Forbidden/Forbidden.test.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) TotalSoft.
2 | // This source code is licensed under the MIT license.
3 |
4 | import React from 'react'
5 | import Forbidden from './Forbidden'
6 | import { render, screen } from 'testingUtils'
7 |
8 | const forbiddenTextValue = 'You are banned from viewing this page!'
9 | const forbiddenTextDefault = 'Not allowed to see this page!'
10 | const forbiddenButtonTextValue = 'Go to page'
11 | const forbiddenButtonTextDefault = 'Go to main page'
12 |
13 | describe('Forbidden', () => {
14 | test('displays the text received through the forbiddenText prop', () => {
15 | render()
16 |
17 | expect(screen.getByText(forbiddenTextValue)).toBeInTheDocument()
18 | })
19 |
20 | test('displays the text received through the forbiddenButtonText prop', () => {
21 | render()
22 |
23 | expect(screen.getByText(forbiddenButtonTextValue)).toBeInTheDocument()
24 | })
25 |
26 | test('default text and default text of the button are in screen', async () => {
27 | render()
28 | const forbiddenText = await screen.findByText(forbiddenTextDefault)
29 | const forbiddenButtonText = await screen.findByText(forbiddenButtonTextDefault)
30 |
31 | expect(forbiddenText).toBeInTheDocument()
32 | expect(forbiddenButtonText).toBeInTheDocument()
33 | })
34 |
35 | test('displays image on the screen', async () => {
36 | render()
37 | const forbiddenImage = screen.getByRole('img')
38 |
39 | expect(forbiddenImage).toHaveAttribute('alt', 'ForbiddenImage')
40 | })
41 | })
42 |
--------------------------------------------------------------------------------
/src/components/feedback/Forbidden/Forbidden.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import PropTypes from 'prop-types'
3 | import Grid from '@mui/material/Grid2'
4 | import forbidden from '../../assets/img/forbidden.png'
5 | import Typography from '../../dataDisplay/Typography'
6 | import Button from '../../buttons/Button'
7 | import { ForbiddenProps } from './types'
8 |
9 | /**
10 | * Used when users don't have access to certain page due to insufficient rights.
11 | */
12 |
13 | const Forbidden: React.FC = ({
14 | forbiddenText = 'Not allowed to see this page!',
15 | forbiddenButtonText = 'Go to main page'
16 | }) => {
17 | return (
18 |
19 |
20 |
21 |
22 |
23 |
24 | {forbiddenText}
25 |
26 |
27 |
28 |
31 |
32 |
33 | )
34 | }
35 |
36 | Forbidden.propTypes = {
37 | /**
38 | * @default 'Not allowed to see this page!'
39 | * Text to be displayed
40 | */
41 | forbiddenText: PropTypes.string,
42 | /**
43 | * @default 'Go to main page'
44 | * Text to be displayed on button
45 | */
46 | forbiddenButtonText: PropTypes.string
47 | }
48 |
49 | export default Forbidden
50 |
--------------------------------------------------------------------------------
/src/components/feedback/Forbidden/index.ts:
--------------------------------------------------------------------------------
1 | export * from './types'
2 | import Forbidden from './Forbidden'
3 | export default Forbidden
4 |
--------------------------------------------------------------------------------
/src/components/feedback/Forbidden/types.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) TotalSoft.
2 | // This source code is licensed under the MIT license.
3 |
4 | export interface ForbiddenProps {
5 | /**
6 | * @default "Not allowed to see this page!"
7 | * Text to be displayed
8 | */
9 | forbiddenText?: string
10 | /**
11 | * @default "Go to main page"
12 | * Text to be displayed on button
13 | */
14 | forbiddenButtonText?: string
15 | }
16 |
--------------------------------------------------------------------------------
/src/components/feedback/LinearProgress/LinearProgress.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { render, screen } from 'testingUtils'
3 | import { LinearProgress } from 'components'
4 |
5 | describe('LinearProgress', () => {
6 | it('renders the label', () => {
7 | render()
8 | expect(screen.getByText('80%')).toBeInTheDocument()
9 | })
10 | })
11 |
--------------------------------------------------------------------------------
/src/components/feedback/LinearProgress/LinearProgressStyles.ts:
--------------------------------------------------------------------------------
1 | import { LinearProgress as MuiLinearProgress, Box } from '@mui/material'
2 | import { styled } from '@mui/material/styles'
3 | import Typography from '../../dataDisplay/Typography'
4 | import { includes } from 'ramda'
5 |
6 | export const LinearProgress: any = styled(MuiLinearProgress, {
7 | shouldForwardProp: prop => !includes(prop, ['showLabel', 'labelProps'])
8 | })(() => ({
9 | '&.MuiLinearProgress-bar': {
10 | height: '4px'
11 | },
12 | '&.MuiLinearProgress-root': {
13 | height: '4px',
14 | overflow: 'hidden'
15 | }
16 | }))
17 |
18 | export const Label = styled(Typography)(() => ({
19 | marginTop: '-21px'
20 | }))
21 |
22 | type ContainerComponentProps = {
23 | global?: boolean
24 | }
25 |
26 | export const ComponentContainer = styled(Box, { shouldForwardProp: prop => prop !== 'global' })(
27 | ({ global }) => ({
28 | display: 'flex',
29 | alignItems: 'center',
30 | ...(global && {
31 | position: 'fixed',
32 | zIndex: 9999,
33 | top: 0,
34 | left: 0,
35 | right: 0,
36 | overflow: 'hidden'
37 | })
38 | })
39 | )
40 |
41 | type LinearProgressContainerProps = {
42 | hasLabel?: boolean
43 | }
44 |
45 | export const LinearProgressContainer = styled(Box, {
46 | shouldForwardProp: prop => prop !== 'hasLabel'
47 | })(({ hasLabel, theme }) => ({
48 | width: '100%',
49 | ...(hasLabel && {
50 | marginRight: theme.spacing(1)
51 | })
52 | }))
53 |
54 | export default LinearProgress
55 |
--------------------------------------------------------------------------------
/src/components/feedback/LinearProgress/index.ts:
--------------------------------------------------------------------------------
1 | import LinearProgress from './LinearProgress'
2 | export default LinearProgress
3 | export * from './types'
4 |
--------------------------------------------------------------------------------
/src/components/feedback/LinearProgress/types.ts:
--------------------------------------------------------------------------------
1 | import { LinearProgressProps as MuiLinearProgressProps } from '@mui/material'
2 | import { TypographyProps } from '../../dataDisplay/Typography'
3 | import { Color } from '../../types'
4 |
5 | type ProgressColor = Exclude | 'grey'
6 |
7 | export interface LinearProgressProps extends Omit {
8 | /**
9 | * @default "grey"
10 | * Color of the component.
11 | */
12 | color?: ProgressColor
13 | /**
14 | * Props applied to the label.
15 | */
16 | labelProps?: TypographyProps
17 | /**
18 | * If true it shows the progress indicator value (%).
19 | */
20 | showLabel?: boolean
21 | /**
22 | * If true, the bar is shown at the top of the page, spanning the entire width
23 | */
24 | global?: boolean
25 | }
26 |
--------------------------------------------------------------------------------
/src/components/feedback/NotFound/NotFound.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import PropTypes from 'prop-types'
3 | import { NotFoundImage, NotFoundText } from './NotFoundStyles'
4 | import notFound from '../../assets/img/notFound.png'
5 | import Grid from '@mui/material/Grid2'
6 | import { NotFoundProps } from './types'
7 |
8 | /**
9 | * Used when a page cannot be found.
10 | */
11 |
12 | const NotFound: React.FC = ({
13 | text = 'Not Found',
14 | details = 'The resource requested could not be found on this server!'
15 | }) => {
16 | return (
17 |
18 |
19 |
20 |
21 | {text}
22 | {details}
23 |
24 | )
25 | }
26 |
27 | NotFound.propTypes = {
28 | /**
29 | * @default 'Not Found'
30 | * The text to be displayed when this component is rendered
31 | */
32 | text: PropTypes.string,
33 | /**
34 | * @default 'The resource requested could not be found on this server!'
35 | * The details to be displayed when this component is rendered
36 | */
37 | details: PropTypes.string
38 | }
39 |
40 | export default NotFound
41 |
--------------------------------------------------------------------------------
/src/components/feedback/NotFound/NotFoundStyles.ts:
--------------------------------------------------------------------------------
1 | import Typography from '@mui/material/Typography'
2 | import { styled } from '@mui/material/styles'
3 |
4 | export const NotFoundText = styled(Typography)(({ theme }) => ({
5 | textAlign: 'center',
6 | fontWeight: 'bold',
7 | fontFamily: theme.typography.defaultFont.fontFamily
8 | }))
9 |
10 | export const NotFoundImage = styled('div')(() => ({
11 | marginBottom: '30px',
12 | marginTop: '50px',
13 | textAlign: 'center'
14 | }))
15 |
16 | export default NotFoundText
17 |
--------------------------------------------------------------------------------
/src/components/feedback/NotFound/index.ts:
--------------------------------------------------------------------------------
1 | export * from './types'
2 | import NotFound from './NotFound'
3 | export default NotFound
4 |
--------------------------------------------------------------------------------
/src/components/feedback/NotFound/types.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) TotalSoft.
2 | // This source code is licensed under the MIT license.
3 |
4 | export interface NotFoundProps {
5 | /**
6 | * @default "Not Found"
7 | * The text to be displayed when this component is rendered
8 | */
9 | text?: string
10 | /**
11 | * @default "The resource requested could not be found on this server!"
12 | * The details to be displayed when this component is rendered
13 | */
14 | details?: string
15 | }
16 |
--------------------------------------------------------------------------------
/src/components/feedback/Toast/index.ts:
--------------------------------------------------------------------------------
1 | export * from './types'
2 | export { default as ToastContainer } from './ToastContainer'
3 | export { default as useToast } from './useToast'
4 | export { default as usePromiseToast } from './usePromiseToast'
--------------------------------------------------------------------------------
/src/components/feedback/Toast/types.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) TotalSoft.
2 | // This source code is licensed under the MIT license.
3 | import { always, cond, equals, T } from 'ramda'
4 | import { Bounce, Flip, ToastOptions as ToastOptionsBase, ToastContainerProps as ToastContainerPropsBase, Slide, Zoom } from 'react-toastify'
5 |
6 | export type TextFontSize = 'small' | 'medium' | 'large'
7 |
8 | export interface ToastContainerProps extends Omit {
9 | /**
10 | * The appearance effect.
11 | * @default Slide
12 | */
13 | transitionType?: 'Slide' | 'Bounce' | 'Zoom' | 'Flip',
14 | /**
15 | * The size of the toast content text.
16 | * @default 'small'
17 | */
18 | textSize?: TextFontSize
19 | }
20 |
21 | export type ToastOptions = Omit & {
22 | transitionType?: 'Slide' | 'Bounce' | 'Zoom' | 'Flip',
23 | actions?: React.ReactNode
24 | }
25 |
26 | export const getTransitionType = cond([
27 | [equals('Slide'), always(Slide)],
28 | [equals('Bounce'), always(Bounce)],
29 | [equals('Flip'), always(Flip)],
30 | [equals('Zoom'), always(Zoom)],
31 | [T, always(Slide)]
32 | ])
--------------------------------------------------------------------------------
/src/components/inputs/Autocomplete/index.ts:
--------------------------------------------------------------------------------
1 | import Autocomplete from './Autocomplete'
2 | export default Autocomplete
3 | export * from './types'
4 |
--------------------------------------------------------------------------------
/src/components/inputs/Autocomplete/utils.ts:
--------------------------------------------------------------------------------
1 | import { emptyString } from '../../utils/constants'
2 | import { any, curry, either, equals, find, head, isEmpty, isNil, prop, type } from 'ramda'
3 |
4 | export const isNilOrEmpty = either(isNil, isEmpty)
5 |
6 | export const extractFirstValue = curry((fns, obj) => {
7 | for (let i = 0; i < fns.length; ++i) {
8 | const result = fns[i](obj)
9 | if (!isNilOrEmpty(result)) return result.toString()
10 | }
11 | return emptyString
12 | })
13 |
14 | export const internalLabel = prop('__internalDisplay')
15 | export const internalValue = prop('__internalInputValue')
16 |
17 | const sameJsType = curry((a, b) => {
18 | if (any(isNil, [a, b])) return true
19 | return equals(type(a), type(b))
20 | })
21 |
22 | export const convertValueToOption = curry((value, options = [], getValue) => {
23 | if (isEmpty(options)) return value
24 | if (sameJsType(value, head(options))) return value
25 | const converted = find(option => getValue(option) == value, options)
26 | return isNil(converted) ? value : converted
27 | })
28 |
--------------------------------------------------------------------------------
/src/components/inputs/DateTime/index.ts:
--------------------------------------------------------------------------------
1 | export * from './types'
2 | import DateTime from './DateTime'
3 | export default DateTime
4 |
--------------------------------------------------------------------------------
/src/components/inputs/DeprecatedAutocomplete/index.ts:
--------------------------------------------------------------------------------
1 | import DeprecatedAutocomplete from './DeprecatedAutocomplete'
2 | export default DeprecatedAutocomplete
3 | export * from './types'
4 |
--------------------------------------------------------------------------------
/src/components/inputs/DynamicField/index.ts:
--------------------------------------------------------------------------------
1 | export * from './types'
2 | import DynamicField from './DynamicField'
3 | export default DynamicField
4 |
--------------------------------------------------------------------------------
/src/components/inputs/DynamicField/types.ts:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { LoadOptions } from '../Autocomplete'
3 |
4 | export enum ControlType {
5 | Text = 'Text',
6 | Integer = 'Integer',
7 | Numeric = 'Numeric',
8 | Date = 'Date',
9 | Checkbox = 'Checkbox',
10 | Autocomplete = 'Autocomplete',
11 | Custom = 'Custom'
12 | }
13 |
14 | export type DynamicFieldProps = {
15 | controlType: ControlType
16 | id?: string
17 | value?: unknown
18 | label?: string
19 | onChange?: (value: unknown) => void
20 | options?: readonly TAutocompleteOptions[]
21 | loadOptions?: LoadOptions
22 | isPaginated?: boolean
23 | error?: boolean
24 | helperText?: React.ReactNode
25 | required?: boolean
26 | readOnly?: boolean
27 | disabled?: boolean
28 | CustomComponent?: (props: TCustomComponentProps) => JSX.Element
29 | customComponentProps?: TCustomComponentProps
30 | [key: string]: any
31 | }
32 |
--------------------------------------------------------------------------------
/src/components/inputs/PasswordField/PasswordField.test.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) TotalSoft.
2 | // This source code is licensed under the MIT license.
3 |
4 | import React from 'react'
5 | import PasswordField from './PasswordField'
6 | import { render, userClick, waitFor, screen, act } from '../../../testingUtils'
7 |
8 | describe('PasswordField', () => {
9 | test('toggles show/hide icons', async () => {
10 | render()
11 | expect(screen.getByTestId('VisibilityOffIcon')).toBeInTheDocument()
12 | act(() => userClick(screen.getByRole('button')))
13 | await waitFor(() => expect(screen.getByTestId('VisibilityIcon')).toBeInTheDocument())
14 | })
15 |
16 | test('hides/displays text when toggling the show button', async () => {
17 | const text = 'password'
18 | render()
19 | const input = screen.getByDisplayValue(text)
20 | expect(input).toHaveAttribute('type', 'password')
21 | act(() => userClick(screen.getByRole('button')))
22 | await waitFor(() => expect(input).toHaveAttribute('type', 'text'))
23 | })
24 | })
25 |
--------------------------------------------------------------------------------
/src/components/inputs/PasswordField/index.ts:
--------------------------------------------------------------------------------
1 | import PasswordField from './PasswordField'
2 | export default PasswordField
3 |
--------------------------------------------------------------------------------
/src/components/inputs/Slider/SliderStyles.ts:
--------------------------------------------------------------------------------
1 | import MuiSlider from '@mui/material/Slider'
2 | import MuiFormControl from '@mui/material/FormControl'
3 | import MuiFormHelperText from '@mui/material/FormHelperText'
4 | import { styled } from '@mui/material/styles'
5 | import TextField from '../TextField'
6 |
7 | export const StyledSlider: any = styled(MuiSlider)(() => ({
8 | ['&.MuiSlider-root']: {
9 | top: '-1px',
10 | margin: 0,
11 | ['& .MuiSlider-markLabel']: {
12 | top: '20px',
13 | fontSize: '14px',
14 | lineHeight: '1.5em'
15 | }
16 | }
17 | }))
18 |
19 | export const StyledTextField = styled(TextField)(() => ({
20 | margin: '-14px 0'
21 | }))
22 |
23 | export const FormControl = styled(MuiFormControl)(() => ({
24 | overflow: 'visible', // fix for mobile horizontal scroll
25 | marginLeft: 0
26 | }))
27 |
28 | export const FormHelperText = styled(MuiFormHelperText)(() => ({
29 | marginLeft: 0
30 | }))
31 |
--------------------------------------------------------------------------------
/src/components/inputs/Slider/index.ts:
--------------------------------------------------------------------------------
1 | export * from './types'
2 | import Slider from './Slider'
3 | export default Slider
4 |
--------------------------------------------------------------------------------
/src/components/inputs/Tags/DisplayTags.tsx:
--------------------------------------------------------------------------------
1 | import React, { ReactElement } from 'react'
2 | import { TagProps } from './types'
3 | import { map } from 'ramda'
4 | import { Chip } from '@mui/material'
5 |
6 | /**
7 | * Renders the tags as chips.
8 | *
9 | * @param value The array of tags to be displayed.
10 | * @param size The size of the chips (default: 'small').
11 | * @param rest Additional props to be passed to the chips.
12 | * @returns The rendered tags as chips.
13 | */
14 | const DisplayTags: React.FC = ({ value, size = 'small', ...rest }) => (
15 | <>
16 | {map(
17 | (tag: string): ReactElement => (
18 |
19 | ),
20 | value
21 | )}
22 | >
23 | )
24 |
25 | export default DisplayTags
26 |
--------------------------------------------------------------------------------
/src/components/inputs/Tags/index.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) TotalSoft.
2 | // This source code is licensed under the MIT license.
3 |
4 | export { default as DisplayTags } from './DisplayTags'
5 | export { default as TagsInput } from './TagsInput'
6 | export * from './types'
7 |
--------------------------------------------------------------------------------
/src/components/inputs/Tags/types.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) TotalSoft.
2 | // This source code is licensed under the MIT license.
3 |
4 | import { ChipProps as MuiChipPops } from '@mui/material'
5 | import { TextFieldProps } from '../TextField'
6 |
7 | export interface TagsInputProps extends Omit {
8 | onChange: (selectedItems: string[]) => void
9 | value?: string[]
10 | placeholder?: string
11 | textFieldProps?: TextFieldProps
12 | }
13 |
14 | export type TagProps = MuiChipPops & {
15 | value: string[]
16 | }
17 |
--------------------------------------------------------------------------------
/src/components/inputs/TextField/TextFieldStyles.ts:
--------------------------------------------------------------------------------
1 | import MuiTextField from '@mui/material/TextField'
2 | import Button from '@mui/material/Button'
3 | import { styled } from '@mui/material/styles'
4 |
5 | const PREFIX = 'StyledTextField'
6 | export const classes = {
7 | label: `${PREFIX}-label`,
8 | input: `${PREFIX}-input`,
9 | stepperFixedWidth: `${PREFIX}-stepper`
10 | }
11 |
12 | export const TextField = styled(MuiTextField)(({ theme }) => ({
13 | [`& .${classes.input}`]: {
14 | '&,&::placeholder': {
15 | ...theme.typography.defaultFont,
16 | fontWeight: '400'
17 | }
18 | },
19 | [`& .${classes.stepperFixedWidth}`]: {
20 | width: '120px'
21 | }
22 | }))
23 |
24 | export const StepButton = styled(Button)(({ theme }) => ({
25 | fontFamily: theme.typography.fontFamily,
26 | minWidth: '28px',
27 | height: '28px',
28 | fontSize: '22px',
29 | fontWeight: 'bold',
30 | borderRadius: 'unset'
31 | }))
32 |
--------------------------------------------------------------------------------
/src/components/inputs/TextField/index.ts:
--------------------------------------------------------------------------------
1 | export * from './types'
2 | import TextField from './TextField'
3 | export default TextField
4 |
--------------------------------------------------------------------------------
/src/components/navigation/NavPills/index.ts:
--------------------------------------------------------------------------------
1 | export * from './types'
2 | import NavPills from './NavPills'
3 | export default NavPills
4 |
--------------------------------------------------------------------------------
/src/components/navigation/Pagination/Pagination.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { render, userClick } from '../../../testingUtils'
3 | import { screen } from '@testing-library/react'
4 | import Pagination from './Pagination'
5 |
6 | const paginationProps = {
7 | count: 100,
8 | pageSize: 10,
9 | page: 0,
10 | rowsPerPageOptions: [10, 20],
11 | onPageChange: jest.fn(),
12 | onRowsPerPageChange: jest.fn()
13 | }
14 |
15 | describe('Pagination', () => {
16 | it('renders default rowsPerPageText', () => {
17 | render()
18 | expect(screen.getByText('Rows per page:')).toBeInTheDocument()
19 | })
20 |
21 | it('onRefresh is called', () => {
22 | const mockRefresh = jest.fn()
23 | render()
24 | const refreshButton = screen.getByTestId('RefreshIcon').parentElement
25 | userClick(refreshButton)
26 | expect(mockRefresh).toHaveBeenCalledTimes(1)
27 | })
28 |
29 | it('renders refresh button', () => {
30 | const mockRefresh = jest.fn()
31 | render()
32 | expect(screen.getByTestId('RefreshIcon')).toBeInTheDocument()
33 | })
34 | })
35 |
--------------------------------------------------------------------------------
/src/components/navigation/Pagination/PaginationStyles.ts:
--------------------------------------------------------------------------------
1 | import { styled } from '@mui/material/styles'
2 |
3 | export const RefreshButtonContainer = styled('div')(() => ({
4 | marginRight: '-15px',
5 | lineHeight: 'normal'
6 | }))
7 |
--------------------------------------------------------------------------------
/src/components/navigation/Pagination/index.ts:
--------------------------------------------------------------------------------
1 | import Pagination from './Pagination'
2 | export default Pagination
3 | export * from './types'
--------------------------------------------------------------------------------
/src/components/navigation/SideMenu/SideMenu.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { act, render, screen, userClick, waitFor } from 'testingUtils'
3 | import SideMenu from './SideMenu'
4 |
5 | const content = 'content'
6 |
7 | describe('SideMenu', () => {
8 | it('doesn\'t display content by default', () => {
9 | render()
10 | expect(screen.getByText(content)).not.toBeVisible()
11 | })
12 |
13 | it('display content when the button is clicked', async () => {
14 | render()
15 | act(() => userClick(screen.getByTestId('MenuOpenIcon').parentElement))
16 | await waitFor(() => expect(screen.getByText(content)).toBeVisible())
17 | })
18 |
19 | it('hides content when clicked outside', async () => {
20 | render()
21 | const button = screen.getByTestId('MenuOpenIcon').parentElement
22 | act(() => userClick(button))
23 | await waitFor(() => expect(screen.getByText(content)).toBeVisible())
24 | act(() => userClick(button.parentElement.parentElement))
25 | await waitFor(() => expect(screen.getByText(content)).not.toBeVisible())
26 | })
27 | })
28 |
--------------------------------------------------------------------------------
/src/components/navigation/SideMenu/index.ts:
--------------------------------------------------------------------------------
1 | import SideMenu from './SideMenu'
2 | export default SideMenu
3 | export * from './types'
4 |
--------------------------------------------------------------------------------
/src/components/navigation/SideMenu/types.ts:
--------------------------------------------------------------------------------
1 | import { SvgIconComponent } from '@mui/icons-material'
2 | import { SvgIconProps } from '@mui/material'
3 | import { IconButtonProps } from 'components/buttons/IconButton'
4 | import { HTMLAttributes } from 'react'
5 |
6 | export interface SideMenuProps {
7 | /**
8 | * Content of the menu
9 | */
10 | content?: React.ReactNode
11 | /**
12 | * @default MenuOpenIcon
13 | * Icon to be displayed on the button
14 | */
15 | icon?: SvgIconComponent
16 | /**
17 | * Props applied to the button
18 | */
19 | buttonProps?: IconButtonProps
20 | /**
21 | * Props applied to the content
22 | */
23 | contentProps?: HTMLAttributes
24 | /**
25 | * Props applied to the icon
26 | */
27 | iconProps?: SvgIconProps
28 | }
29 |
--------------------------------------------------------------------------------
/src/components/surfaces/Accordion/Accordion.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { render, screen } from 'testingUtils'
3 | import Accordion from './index'
4 |
5 | const mockedContent = { title: 'Title', content: 'Details of the content' }
6 |
7 | describe('Accordion', () => {
8 | it('renders title content', () => {
9 | render()
10 | expect(screen.getByText(mockedContent.title)).toBeInTheDocument()
11 | })
12 |
13 | it('renders details content', () => {
14 | render()
15 | expect(screen.getByText(mockedContent.content)).toBeInTheDocument()
16 | })
17 |
18 | it('renders expand more icon', () => {
19 | render()
20 | expect(screen.getByTestId('ExpandMoreIcon')).toBeInTheDocument()
21 | })
22 | })
23 |
24 | const mockedArrayContent = [{ title: 'Title', content: 'Details of the content' }] as {
25 | title?: string
26 | content?: string
27 | }[]
28 |
29 | describe('Accordion List', () => {
30 | it('renders title content', () => {
31 | render()
32 | expect(screen.getByText(mockedArrayContent[0].title)).toBeInTheDocument()
33 | })
34 |
35 | it('renders details content', () => {
36 | render()
37 | expect(screen.getByText(mockedArrayContent[0].content)).toBeInTheDocument()
38 | })
39 | })
40 |
--------------------------------------------------------------------------------
/src/components/surfaces/Accordion/AccordionStyles.ts:
--------------------------------------------------------------------------------
1 | import MuiAccordionSummary from '@mui/material/AccordionSummary'
2 | import { styled } from '@mui/material/styles'
3 | import { includes } from 'ramda'
4 | import { AccordionSummaryProps } from './types'
5 | import { Theme } from '@mui/material'
6 |
7 | type StyledProps = { theme: Theme } & AccordionSummaryProps
8 |
9 | export const AccordionSummary = styled(MuiAccordionSummary, {
10 | shouldForwardProp: prop => !includes(prop, ['variant'])
11 | })(({ theme, variant }: StyledProps) => ({
12 | ...(variant === 'filled' && { backgroundColor: theme.palette.grey[200] })
13 | }))
14 |
--------------------------------------------------------------------------------
/src/components/surfaces/Accordion/index.ts:
--------------------------------------------------------------------------------
1 | import Accordion from './Accordion'
2 | export default Accordion
3 | export * from './types'
4 |
--------------------------------------------------------------------------------
/src/components/surfaces/Card/CardActions/CardActions.test.tsx:
--------------------------------------------------------------------------------
1 | import getTheme from '../../../themes'
2 | import React from 'react'
3 | import { render, screen } from 'testingUtils'
4 | import CardActions from './CardActions'
5 | import Button from '../../../buttons/Button'
6 |
7 | const theme = getTheme()
8 |
9 | describe('CardActions', () => {
10 | it('when `filled` property is set, teh card has a grey background color', () => {
11 | render(
12 |
13 |
14 |
15 | )
16 | expect(screen.getByRole('button').parentElement).toHaveStyle(`background-color: ${theme.palette.grey[200]}`)
17 | })
18 |
19 | it('has `standard` variant by default', () => {
20 | render(
21 |
22 |
23 |
24 | )
25 | expect(screen.getByRole('button').parentElement).not.toHaveStyle(`background-color: ${theme.palette.grey[200]}`)
26 | })
27 |
28 | it('displays actions on the left by default', () => {
29 | render(
30 |
31 |
32 |
33 | )
34 | expect(screen.getByRole('button').parentElement).toHaveStyle('justify-content: unset')
35 | })
36 |
37 | it('displays actions on the right when `align` is set to `right`', () => {
38 | render(
39 |
40 |
41 |
42 | )
43 | expect(screen.getByRole('button').parentElement).toHaveStyle('justify-content: flex-end')
44 | })
45 | })
46 |
--------------------------------------------------------------------------------
/src/components/surfaces/Card/CardActions/CardActions.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import PropTypes from 'prop-types'
3 | import MuiCardActions from './CardActionsStyles'
4 | import { CardActionsProps } from '../types'
5 |
6 | const CardActions: React.FC = props => {
7 | return
8 | }
9 |
10 | CardActions.propTypes = {
11 | /**
12 | * If 'true', the card footer will be filled with a grayish color
13 | * @default false
14 | */
15 | filled: PropTypes.bool,
16 | /**
17 | * Align actions.
18 | * @default 'left'
19 | */
20 | align: PropTypes.oneOf(['left', 'right', 'center'])
21 | }
22 |
23 | export default CardActions
24 |
--------------------------------------------------------------------------------
/src/components/surfaces/Card/CardActions/CardActionsStyles.ts:
--------------------------------------------------------------------------------
1 | import { Theme } from '@mui/material'
2 | import MuiCardActions from '@mui/material/CardActions'
3 | import { styled } from '@mui/material/styles'
4 | import { T, always, cond, equals, includes } from 'ramda'
5 | import { ActionAlign } from '../types'
6 |
7 | type StyledProps = { theme: Theme; filled: boolean; align: ActionAlign }
8 |
9 | const contentAlignment = cond([
10 | [equals('left'), always('flex-start')],
11 | [equals('right'), always('flex-end')],
12 | [equals('center'), always('center')],
13 | [T, always('unset')]
14 | ])
15 |
16 | const CardActions = styled(MuiCardActions, {
17 | shouldForwardProp: prop => !includes(prop, ['align', 'filled'])
18 | })(({ theme, filled, align }: Partial) => ({
19 | ...(filled && {
20 | backgroundColor: theme?.palette.grey[200],
21 | minHeight: '48px',
22 | padding: theme?.spacing(2, 3)
23 | }),
24 | justifyContent: contentAlignment(align)
25 | }))
26 |
27 | export default CardActions
28 |
--------------------------------------------------------------------------------
/src/components/surfaces/Card/CardActions/index.ts:
--------------------------------------------------------------------------------
1 | import CardActions from './CardActions'
2 | export default CardActions
3 |
--------------------------------------------------------------------------------
/src/components/surfaces/Card/CardHeader/CardHeader.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { render, screen } from 'testingUtils'
3 | import CardHeader from './CardHeader'
4 | import getTheme from '../../../themes'
5 | import Button from '../../../buttons/Button'
6 |
7 | const theme = getTheme()
8 |
9 | const title = 'Title'
10 |
11 | describe('CardHeader', () => {
12 | it('when `filled` property is set, the card has a grey background color', () => {
13 | render()
14 | expect(screen.getByText(title)?.parentElement?.parentElement?.parentElement).toHaveStyle(
15 | `background-color: ${theme.palette.grey[200]}`
16 | )
17 | })
18 |
19 | it('has `elevation` variant by default', () => {
20 | render()
21 | expect(screen.getByText(title)?.parentElement?.parentElement).not.toHaveStyle(
22 | `background-color: ${theme.palette.grey[200]}`
23 | )
24 | })
25 |
26 | it('when `actions` is not an array, renders the node as it is', () => {
27 | render(one} />)
28 | expect(screen.getByRole('button')).toBeInTheDocument()
29 | })
30 | })
31 |
--------------------------------------------------------------------------------
/src/components/surfaces/Card/CardHeader/CardHeader.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import PropTypes from 'prop-types'
3 | import MuiCardHeader from './CardHeaderStyles'
4 | import { isValidElement } from 'react'
5 | import Typography from '../../../dataDisplay/Typography'
6 | import { CardHeaderProps } from '../types'
7 |
8 | const CardHeader: React.FC = ({ actions, title, ...rest }) => {
9 | return (
10 |
18 | {title}
19 |
20 | )
21 | ) : undefined
22 | }
23 | {...rest}
24 | />
25 | )
26 | }
27 |
28 | CardHeader.propTypes = {
29 | /**
30 | * Actions to be displayed in the right corner of the card. If an array, will display all items with spacing between them.
31 | */
32 | actions: PropTypes.node,
33 | /**
34 | * Card title
35 | */
36 | title: PropTypes.node,
37 | /**
38 | * Indicates if the parent Card component contains an icon element or not
39 | */
40 | hasIcon: PropTypes.bool,
41 | /**
42 | * @default 'secondary'
43 | * Icon color.
44 | */
45 | iconColor: PropTypes.oneOf(['primary', 'secondary', 'info', 'success', 'warning', 'error', 'rose']),
46 | /**
47 | * If 'true', the card header will be filled with a grayish color
48 | * @default false
49 | */
50 | filled: PropTypes.bool
51 | }
52 |
53 | export default CardHeader
54 |
--------------------------------------------------------------------------------
/src/components/surfaces/Card/CardHeader/CardHeaderStyles.ts:
--------------------------------------------------------------------------------
1 | import { Palette, Theme } from '@mui/material'
2 | import MuiCardHeader from '@mui/material/CardHeader'
3 | import { styled } from '@mui/material/styles'
4 | import { includes } from 'ramda'
5 | import { CardColor } from '../types'
6 |
7 | type StyledProps = {
8 | theme: Theme
9 | filled: boolean
10 | hasIcon: boolean
11 | iconColor: CardColor
12 | avatarProps: any
13 | headerContentProps: any
14 | }
15 |
16 | const CardHeader = styled(MuiCardHeader, {
17 | shouldForwardProp: prop =>
18 | !includes(prop, ['variant', 'hasIcon', 'iconColor', 'filled', 'avatarProps', 'headerContentProps'])
19 | })(
20 | ({
21 | theme,
22 | filled,
23 | hasIcon,
24 | iconColor = 'secondary' as CardColor & keyof Palette,
25 | avatarProps,
26 | headerContentProps
27 | }: Partial) => ({
28 | ['&.MuiCardHeader-root']: {
29 | ...(filled && { backgroundColor: theme?.palette.grey[200], minHeight: '48px' })
30 | },
31 | ['& .MuiCardHeader-avatar']: {
32 | ...(hasIcon && {
33 | width: '3rem',
34 | height: '3rem',
35 | borderRadius: '0.75rem',
36 | background: `linear-gradient(195deg, ${theme?.palette[iconColor].light}, ${theme?.palette[iconColor].main})`,
37 | position: 'absolute',
38 | top: '-20px',
39 | ...avatarProps
40 | })
41 | },
42 | ['& .MuiCardHeader-content']: {
43 | ...(hasIcon && {
44 | paddingLeft: '80px'
45 | }),
46 | ...headerContentProps
47 | },
48 | ['& .MuiCardHeader-action']: {
49 | gap: '0.5rem',
50 | display: 'flex',
51 | flex: '0 1 auto',
52 | flexWrap: 'wrap',
53 | justifyContent: 'flex-end'
54 | }
55 | })
56 | )
57 |
58 | export default CardHeader
59 |
--------------------------------------------------------------------------------
/src/components/surfaces/Card/CardHeader/index.ts:
--------------------------------------------------------------------------------
1 | import CardHeader from './CardHeader'
2 | export default CardHeader
3 |
--------------------------------------------------------------------------------
/src/components/surfaces/Card/index.ts:
--------------------------------------------------------------------------------
1 | export { default as Card } from './Card'
2 | export { default as CardActions } from './CardActions'
3 | export { default as CardHeader } from './CardHeader'
4 | export * from './types'
5 |
--------------------------------------------------------------------------------
/src/components/surfaces/CollapseCard/index.ts:
--------------------------------------------------------------------------------
1 | export * from './types'
2 | import CollapseCard from './CollapseCard'
3 | export default CollapseCard
4 |
--------------------------------------------------------------------------------
/src/components/surfaces/CollapseCard/types.ts:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { CardProps } from '../Card'
3 |
4 | export interface CollapseCardProps extends Omit {
5 | /**
6 | * Content of the component.
7 | */
8 | content?: React.ReactNode
9 | /**
10 | * Content of the subheader.
11 | */
12 | subheader?: React.ReactNode
13 | /**
14 | * If true, the card will be expanded by default.
15 | * @default false
16 | */
17 | defaultExpanded?: boolean
18 | /**
19 | * If true, the card will be expanded.
20 | */
21 | expanded?: boolean
22 | /**
23 | * If true, the card can be expanded.
24 | * @deprecated Use `Card` component instead
25 | */
26 | canExpand?: boolean
27 | /**
28 | * Callback fired on toggle.
29 | */
30 | onToggle?: (event: React.SyntheticEvent, expanded: boolean) => void
31 | /**
32 | * If true, the subheader will be hidden when the card is expanded.
33 | */
34 | hideSubheaderOnExpand?: boolean
35 | /**
36 | * If true, the card will toggle when clicking on the whole header, not just the expand button.
37 | */
38 | toggleOnHeaderClick?: boolean
39 | }
40 |
--------------------------------------------------------------------------------
/src/components/surfaces/StatsCard/StatsCard.test.tsx:
--------------------------------------------------------------------------------
1 | import { Button, StatsCard, getTheme } from '../../index'
2 | import React from 'react'
3 | import { render, screen } from 'testingUtils'
4 | import AttachMoneyIcon from '@mui/icons-material/AttachMoney'
5 |
6 | const theme = getTheme()
7 |
8 | describe('StatsCard', () => {
9 | it('renders footer', () => {
10 | render(} />)
11 | expect(screen.getByRole('button')).toBeInTheDocument()
12 | })
13 |
14 | it('renders card header', () => {
15 | const title = 'StatsCard title'
16 | const description = 'StatsCard description'
17 |
18 | render()
19 |
20 | expect(screen.getByText(title)).toBeInTheDocument()
21 | expect(screen.getByText(description)).toBeInTheDocument()
22 | })
23 |
24 | it('when `icon` is received, applies a background of `iconColor`', () => {
25 | const iconColor = 'warning'
26 | render()
27 | expect(screen.getByTestId('AttachMoneyIcon').parentElement).toHaveStyle(
28 | `background: linear-gradient(195deg, ${theme.palette[iconColor].light}, ${theme.palette[iconColor].main})`
29 | )
30 | })
31 |
32 | it('has `standard` variant by default', () => {
33 | render(ok} />)
34 | expect(screen.getByRole('button').parentElement).not.toHaveStyle(`background-color: ${theme.palette.grey[200]}`)
35 | })
36 |
37 | it('has iconColor set to info by default', () => {
38 | render()
39 | expect(screen.getByTestId('AttachMoneyIcon').parentElement).toHaveStyle(
40 | `background: linear-gradient(195deg, ${theme.palette['info'].light}, ${theme.palette['info'].main})`
41 | )
42 | })
43 | })
44 |
--------------------------------------------------------------------------------
/src/components/surfaces/StatsCard/StatsCardStyles.ts:
--------------------------------------------------------------------------------
1 | import MuiCardContent from '@mui/material/CardContent'
2 | import { styled } from '@mui/material/styles'
3 | import { Card, CardActions, CardHeader, Typography } from '../../index'
4 |
5 | export const StyledCard = styled(Card)(({ theme }) => ({
6 | display: 'inline-block',
7 | position: 'relative',
8 | width: '100%',
9 | minWidth: '150%',
10 | margin: '25px 0',
11 | boxShadow: '0 1px 4px 0 rgba(0, 0, 0, 0.14)',
12 | borderRadius: '6px',
13 | color: theme.palette.primary.main,
14 | background: '#fff',
15 | overflow: 'visible'
16 | }))
17 |
18 | export const StyledCardHeader = styled(CardHeader)(() => ({
19 | paddingTop: '5px'
20 | }))
21 |
22 | export const CardContent = styled(MuiCardContent)(() => ({
23 | textAlign: 'right',
24 | fontSize: '10px',
25 | paddingTop: '10px',
26 | padding: '2px 10px'
27 | }))
28 |
29 | export const StyledCardActions = styled(CardActions)(({ theme }) => ({
30 | margin: '0 20px 10px',
31 | height: 'auto',
32 | padding: '2px 0 0 0',
33 | ...theme.typography.defaultFont
34 | }))
35 |
36 | export const CardTitle = styled(Typography)(({ theme }) => ({
37 | marginBottom: '0',
38 | color: theme.palette.grey[500],
39 | margin: '0 0 5px'
40 | }))
41 |
42 | export const CardDescription = styled(Typography)(() => ({
43 | margin: '0'
44 | }))
45 |
46 | export const iconStyle = {
47 | color: '#FFFFFF',
48 | width: '2.5rem',
49 | height: '2.5rem',
50 | margin: 'auto',
51 | padding: '2px'
52 | }
53 |
--------------------------------------------------------------------------------
/src/components/surfaces/StatsCard/index.ts:
--------------------------------------------------------------------------------
1 | export * from './types'
2 | import StatsCard from './StatsCard'
3 | export default StatsCard
4 |
--------------------------------------------------------------------------------
/src/components/surfaces/StatsCard/types.ts:
--------------------------------------------------------------------------------
1 | import { SvgIconComponent } from '@mui/icons-material'
2 | import type { CardActionsProps, CardColor, CardHeaderProps, CardVariant } from '../../index'
3 |
4 | export interface StatsCardProps {
5 | /**
6 | * Icon to be displayed.
7 | */
8 | icon?: SvgIconComponent
9 | /**
10 | * @default 'info'
11 | * Icon color.
12 | */
13 | iconColor?: CardColor
14 | /**
15 | * Content of the title.
16 | */
17 | title?: React.ReactNode
18 | /**
19 | * Content of the description.
20 | */
21 | description?: React.ReactNode
22 | /**
23 | * Footer to be displayed at the bottom of the card.
24 | */
25 | footer?: React.ReactNode
26 | /**
27 | * @default 'elevation'
28 | * Variant to use.
29 | */
30 | variant?: CardVariant
31 | /**
32 | * Shadow depth, corresponds to `dp` in the spec.
33 | * It accepts values between 0 and 24 inclusive.
34 | * @default 1
35 | */
36 | elevation?: number
37 | /**
38 | * Props applied to the CardActions component.
39 | */
40 | footerProps?: CardActionsProps
41 | /**
42 | * @default {}
43 | * Props applied to the CardHeader component.
44 | */
45 | headerProps?: CardHeaderProps
46 | }
47 |
--------------------------------------------------------------------------------
/src/components/themes/blueTheme.ts:
--------------------------------------------------------------------------------
1 | import { PaletteOptions, Theme, ThemeOptions, createTheme } from '@mui/material'
2 | import componentsOverride from './common/overrides'
3 | import generatePalette from './common/palette'
4 | import { generateTypography } from './common/typography'
5 | import { generateShadows, generateCustomShadows } from './common/shadows'
6 | import table from './common/table'
7 |
8 | const palette = generatePalette({
9 | primary: {
10 | lighter: '#81b8f8',
11 | light: '#4c88c5',
12 | main: '#00497b',
13 | dark: '#003266',
14 | darker: '#000a3b',
15 | contrastText: '#fff',
16 | rgba: 'rgba(0, 91, 148, 1)'
17 | },
18 | secondary: {
19 | lighter: '#99c0ed',
20 | light: '#66a1e5',
21 | main: '#3382DC',
22 | dark: '#1e61ad',
23 | darker: '#144174',
24 | contrastText: '#fff',
25 | rgba: 'rgba(51, 130, 220, 1)'
26 | },
27 | background: {
28 | default: '#F5F8FA',
29 | paper: '#fff'
30 | },
31 | sideMenu: {
32 | bgColor: '#BCE4FA',
33 | color: '#00385F',
34 | hoverBgColor: '#DFF2FD',
35 | hoverTextColor: '#00385F',
36 | bgOpacity: '1',
37 | activeBgColor: '#00497b'
38 | }
39 | } as PaletteOptions)
40 |
41 | const blueTheme: Theme = createTheme({
42 | palette,
43 | shape: { borderRadius: 8 },
44 | typography: generateTypography(palette),
45 | table,
46 | shadows: generateShadows(palette),
47 | customShadows: generateCustomShadows(palette)
48 | } as ThemeOptions)
49 |
50 | blueTheme.components = componentsOverride(blueTheme)
51 |
52 | export default blueTheme
53 |
--------------------------------------------------------------------------------
/src/components/themes/common/overrides/Autocomplete.ts:
--------------------------------------------------------------------------------
1 | import { Theme } from '@mui/material/styles'
2 | import { CustomComponents } from '../../types'
3 |
4 | export default function Autocomplete(theme: Theme): CustomComponents {
5 | return {
6 | MuiAutocomplete: {
7 | styleOverrides: {
8 | inputRoot: (props: any) =>
9 | !props.ownerState.multiple && {
10 | '& .MuiAutocomplete-input': {
11 | width: 'fit-content',
12 | minWidth: 'fit-content'
13 | }
14 | },
15 | input: {
16 | display: 'flex',
17 | whiteSpace: 'nowrap'
18 | },
19 | noOptions: {
20 | ...theme.typography.defaultFont,
21 | padding: `${theme.spacing()}px ${theme.spacing(2)}px`,
22 | color: 'textSecondary'
23 | },
24 | option: {
25 | div: {
26 | ...theme.typography.defaultFont,
27 | display: 'block',
28 | whiteSpace: 'nowrap',
29 | overflow: 'hidden',
30 | textOverflow: 'ellipsis',
31 | width: '100%'
32 | }
33 | }
34 | }
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/components/themes/common/overrides/Button.ts:
--------------------------------------------------------------------------------
1 | import { Theme } from '@mui/material'
2 | import { CustomComponents } from '../../types'
3 |
4 | export default function Button({ palette, customShadows }: Theme): CustomComponents {
5 | return {
6 | MuiButton: {
7 | styleOverrides: {
8 | root: {
9 | borderRadius: '8px',
10 | '&:hover': {
11 | boxShadow: 'none'
12 | }
13 | },
14 | sizeTiny: {}, // adds the 'tiny' size prop type which is not present in MUI
15 | sizeLarge: {
16 | height: 48
17 | },
18 | containedInherit: {
19 | color: palette.grey[800],
20 | boxShadow: customShadows.z8,
21 | '&:hover': {
22 | backgroundColor: palette.grey[400]
23 | }
24 | },
25 | outlinedInherit: {
26 | border: `1px solid ${palette.grey[500_32]}`,
27 | '&:hover': {
28 | backgroundColor: palette.action.hover
29 | }
30 | },
31 | textInherit: {
32 | '&:hover': {
33 | backgroundColor: palette.action.hover
34 | }
35 | }
36 | }
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/components/themes/common/overrides/Card.ts:
--------------------------------------------------------------------------------
1 | import { Theme } from '@mui/material'
2 | import { CustomComponents } from '../../types'
3 |
4 | export default function Card(theme: Theme): CustomComponents {
5 | return {
6 | MuiCard: {
7 | styleOverrides: {
8 | root: {
9 | boxShadow: theme.shadows[5],
10 | borderRadius: Number(theme.shape.borderRadius) * 2,
11 | position: 'relative',
12 | zIndex: 0 // Fix Safari overflow: hidden with border radius
13 | }
14 | }
15 | },
16 | MuiCardHeader: {
17 | defaultProps: {
18 | titleTypographyProps: { variant: 'h6' },
19 | subheaderTypographyProps: { variant: 'body2' }
20 | },
21 | styleOverrides: {
22 | root: {
23 | padding: theme.spacing(2, 3)
24 | },
25 | content: {
26 | maxWidth: `calc(100% - ${theme.spacing(4)})`
27 | },
28 | title: {
29 | whiteSpace: 'nowrap',
30 | overflow: 'hidden',
31 | textOverflow: 'ellipsis'
32 | }
33 | }
34 | },
35 | MuiCardContent: {
36 | styleOverrides: {
37 | root: {
38 | padding: theme.spacing(1, 3, 3, 3)
39 | }
40 | }
41 | },
42 | MuiCardActions: {
43 | styleOverrides: {
44 | root: {
45 | padding: theme.spacing(0, 3, 3)
46 | }
47 | }
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/components/themes/common/overrides/Chip.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) TotalSoft.
2 | // This source code is licensed under the MIT license.
3 |
4 | import { Theme } from '@mui/material'
5 | import { CustomComponents } from '../../types'
6 |
7 | export default function Chip(theme: Theme): CustomComponents {
8 | return {
9 | MuiChip: {
10 | styleOverrides: {
11 | root: {
12 | margin: theme.spacing(0.5, 0.25)
13 | },
14 | deleteIcon: {
15 | variants: [
16 | {
17 | props: { variant: 'filled' },
18 | style: {
19 | color: 'white'
20 | }
21 | },
22 | {
23 | props: { variant: 'filled', color: 'default' },
24 | style: {
25 | color: theme.palette.grey[700],
26 | ':hover': { color: theme.palette.grey[900] }
27 | }
28 | }
29 | ]
30 | }
31 | },
32 | variants: [
33 | {
34 | props: { variant: 'filled', color: 'default' },
35 | style: {
36 | color: theme.palette.grey[900],
37 | backgroundColor: theme.palette.grey[300]
38 | }
39 | }
40 | ]
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/components/themes/common/overrides/Divider.ts:
--------------------------------------------------------------------------------
1 | import { CustomComponents } from '../../types'
2 |
3 | export default function Divider(): CustomComponents {
4 | return {
5 | MuiDivider: {
6 | styleOverrides: {
7 | root: {
8 | borderTop: '0px solid rgba(0, 0, 0, 0.12)',
9 | borderRight: '0px solid rgba(0, 0, 0, 0.12)',
10 | borderLeft: '0px solid rgba(0, 0, 0, 0.12)',
11 | borderBottom: 'none',
12 | margin: '1rem 0px',
13 | height: '0.0625rem',
14 | width: '100%',
15 | backgroundColor: 'transparent',
16 | backgroundImage: 'linear-gradient(to right, rgba(52, 71, 103, 0), rgba(52, 71, 103, 0.4), rgba(52, 71, 103, 0))',
17 | opacity: '0.45'
18 | },
19 | vertical: {
20 | borderTop: '0px solid rgba(0, 0, 0, 0.12)',
21 | borderRight: '0px solid rgba(0, 0, 0, 0.12)',
22 | borderLeft: '0px solid rgba(0, 0, 0, 0.12)',
23 | borderBottom: 'none',
24 | margin: '0px 1rem',
25 | width: '0.0625rem',
26 | height: '100%',
27 | backgroundColor: 'transparent',
28 | backgroundImage: 'linear-gradient(rgba(52, 71, 103, 0), rgba(52, 71, 103, 0.4), rgba(52, 71, 103, 0))',
29 | opacity: '0.45'
30 | }
31 | }
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/components/themes/common/overrides/TextField.ts:
--------------------------------------------------------------------------------
1 | import { Theme } from '@mui/material/styles'
2 | import { CustomComponents } from '../../types'
3 |
4 | export default function TextField(theme: Theme): CustomComponents {
5 | return {
6 | MuiFormHelperText: {
7 | styleOverrides: {
8 | root: {
9 | '&.Mui-error': {
10 | marginTop: 0,
11 | lineHeight: 1
12 | }
13 | }
14 | }
15 | },
16 | MuiTextField: {
17 | defaultProps: {
18 | variant: 'standard'
19 | },
20 | styleOverrides: {
21 | root: {
22 | ...theme.typography.defaultFont
23 | }
24 | }
25 | },
26 | MuiInput: {
27 | styleOverrides: {
28 | root: {
29 | ...theme.typography.defaultFont,
30 | fontWeight: '400'
31 | }
32 | }
33 | },
34 | MuiInputLabel: {
35 | styleOverrides: {
36 | root: {
37 | ...theme.typography.defaultFont,
38 | fontWeight: '400',
39 | lineHeight: '1.42857'
40 | }
41 | }
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/components/themes/common/overrides/index.ts:
--------------------------------------------------------------------------------
1 | import Card from './Card'
2 | import Button from './Button'
3 | import Divider from './Divider'
4 | import TextField from './TextField'
5 | import { Theme } from '@mui/material'
6 | import { CustomComponents } from '../../types'
7 | import Autocomplete from './Autocomplete'
8 | import Chip from './Chip'
9 |
10 | const componentsOverride = (theme: Theme): CustomComponents => ({
11 | ...Card(theme),
12 | ...Button(theme),
13 | ...Divider(),
14 | ...TextField(theme),
15 | ...Autocomplete(theme),
16 | ...Chip(theme)
17 | })
18 | export default componentsOverride
19 |
--------------------------------------------------------------------------------
/src/components/themes/common/table.ts:
--------------------------------------------------------------------------------
1 | const table = {
2 | main: {
3 | marginTop: '15px',
4 | marginBottom: '15px',
5 | borderSpacing: 0
6 | },
7 | tableHeader: {
8 | textAlign: 'left',
9 | backgroundColor: '#00497b',
10 | padding: '10px',
11 | borderBottom: '1px solid #ddd',
12 | color: 'white'
13 | },
14 | tableContent: {
15 | textAlign: 'left',
16 | padding: '10px ',
17 | borderBottom: '1px solid #eee'
18 | },
19 | itemSelected: {
20 | background: '#c1c1c1',
21 | color: 'white'
22 | }
23 | }
24 |
25 | export default table
26 |
--------------------------------------------------------------------------------
/src/components/themes/common/typography.ts:
--------------------------------------------------------------------------------
1 | import { PaletteOptions } from '@mui/material'
2 | import { TypographyOptions } from '@mui/material/styles/createTypography'
3 |
4 | export const defaultFont = {
5 | fontFamily: 'Source Sans Pro',
6 | fontSize: 14,
7 | lineHeight: '1.5em',
8 | fontWeight: '300',
9 | letterSpacing: '0.02857em'
10 | }
11 |
12 | export const generateTypography = (palette: PaletteOptions) =>
13 | ({
14 | ...defaultFont,
15 | defaultFont,
16 | useNextVariants: true,
17 | htmlFontSize: 14,
18 | fontWeightMedium: 300,
19 | button: {
20 | ...defaultFont,
21 | textAlign: 'center',
22 | fontStretch: 'normal',
23 | fontStyle: 'normal'
24 | },
25 | body: defaultFont,
26 | header: {
27 | title: {
28 | borderRadius: '3px',
29 | textTransform: 'none',
30 | fontWeight: 'bold',
31 | color: palette.primary.main,
32 | '&:hover,&:focus': {
33 | background: 'transparent'
34 | }
35 | }
36 | }
37 | } as TypographyOptions)
38 |
--------------------------------------------------------------------------------
/src/components/themes/defaultTheme.ts:
--------------------------------------------------------------------------------
1 | import { PaletteOptions, Theme, ThemeOptions, createTheme } from '@mui/material'
2 | import componentsOverride from './common/overrides'
3 | import generatePalette from './common/palette'
4 | import { generateTypography } from './common/typography'
5 | import { generateShadows, generateCustomShadows } from './common/shadows'
6 | import table from './common/table'
7 |
8 | const palette = generatePalette({
9 | primary: {
10 | lighter: '#b0b0b0',
11 | light: '#818181',
12 | main: '#555555',
13 | dark: '#2c2c2c',
14 | darker: '#000000',
15 | contrastText: '#fff',
16 | rgba: 'rgba(85, 85, 85, 1)'
17 | },
18 | secondary: {
19 | lighter: '#a8ffff',
20 | light: '#6ff9ff',
21 | main: '#26C6DA',
22 | dark: '#0095a8',
23 | darker: '#006779',
24 | contrastText: '#fff',
25 | rgba: 'rgba(38, 198, 218, 1)'
26 | },
27 | background: {
28 | default: '#fff',
29 | paper: '#fff'
30 | },
31 | sideMenu: {
32 | bgColor: '#000000d9',
33 | color: '#fff',
34 | hoverBgColor: 'rgba(200, 200, 200, 0.2)',
35 | hoverTextColor: '#fff',
36 | bgOpacity: '0.8',
37 | activeBgColor: '#26C6DA'
38 | }
39 | } as PaletteOptions)
40 |
41 | const defaultTheme: Theme = createTheme({
42 | palette,
43 | shape: { borderRadius: 8 },
44 | typography: generateTypography(palette),
45 | table,
46 | shadows: generateShadows(palette),
47 | customShadows: generateCustomShadows(palette)
48 | } as ThemeOptions)
49 |
50 | defaultTheme.components = componentsOverride(defaultTheme)
51 |
52 | export default defaultTheme
53 |
--------------------------------------------------------------------------------
/src/components/themes/greenTheme.ts:
--------------------------------------------------------------------------------
1 | import { PaletteOptions, Theme, ThemeOptions, createTheme } from '@mui/material'
2 | import componentsOverride from './common/overrides'
3 | import generatePalette from './common/palette'
4 | import { generateTypography } from './common/typography'
5 | import { generateShadows, generateCustomShadows } from './common/shadows'
6 | import table from './common/table'
7 |
8 | const palette = generatePalette({
9 | primary: {
10 | lighter: '#9dffd4',
11 | light: '#67eaa2',
12 | main: '#005604',
13 | dark: '#008647',
14 | darker: '#00581e',
15 | contrastText: '#fff',
16 | rgba: 'rgba(38, 198, 218, 1)'
17 | },
18 | secondary: {
19 | lighter: '#6db45f',
20 | light: '#3d8433',
21 | main: '#2ab773',
22 | dark: '#002c00',
23 | darker: '#003000',
24 | contrastText: '#fff',
25 | rgba: 'rgb(39 108 37)'
26 | },
27 | background: {
28 | default: '#eff7f0',
29 | paper: '#fff'
30 | },
31 | sideMenu: {
32 | bgColor: '#7eb58b',
33 | color: '#005604',
34 | hoverBgColor: 'rgb(239,247,240, 0.5)',
35 | hoverTextColor: '#005604',
36 | bgOpacity: '0.8',
37 | focusBgColor: '#2a912f',
38 | activeBgColor: '#005604'
39 | }
40 | } as PaletteOptions)
41 |
42 | const greenTheme: Theme = createTheme({
43 | palette,
44 | shape: { borderRadius: 8 },
45 | typography: generateTypography(palette),
46 | table,
47 | shadows: generateShadows(palette),
48 | customShadows: generateCustomShadows(palette)
49 | } as ThemeOptions)
50 |
51 | greenTheme.components = componentsOverride(greenTheme)
52 |
53 | export default greenTheme
54 |
--------------------------------------------------------------------------------
/src/components/themes/index.ts:
--------------------------------------------------------------------------------
1 | import defaultTheme from './defaultTheme'
2 | import blueTheme from './blueTheme'
3 | import greenTheme from './greenTheme'
4 | import lightBlueTheme from './lightBlueTheme'
5 | import orangeTheme from './orangeTheme'
6 | import redTheme from './redTheme'
7 | import vividOrangeTheme from './vividOrangeTheme'
8 | import { Theme } from '@mui/material'
9 |
10 | const defaultCtx = { globals: { theme: 'default' } }
11 | const getTheme = (context = defaultCtx): Theme => {
12 | switch (context.globals.theme) {
13 | case 'green':
14 | return greenTheme
15 | case 'blue':
16 | return blueTheme
17 | case 'orange':
18 | return orangeTheme
19 | case 'red':
20 | return redTheme
21 | case 'vividOrange':
22 | return vividOrangeTheme
23 | case 'lightBlue':
24 | return lightBlueTheme
25 | default:
26 | return defaultTheme
27 | }
28 | }
29 |
30 | export default getTheme
31 | export { defaultTheme, blueTheme, greenTheme, lightBlueTheme, orangeTheme, redTheme, vividOrangeTheme }
32 |
--------------------------------------------------------------------------------
/src/components/themes/lightBlueTheme.ts:
--------------------------------------------------------------------------------
1 | import { PaletteOptions, Theme, ThemeOptions, createTheme } from '@mui/material'
2 | import componentsOverride from './common/overrides'
3 | import generatePalette from './common/palette'
4 | import { generateTypography } from './common/typography'
5 | import { generateShadows, generateCustomShadows } from './common/shadows'
6 | import table from './common/table'
7 |
8 | const palette = generatePalette({
9 | primary: {
10 | lighter: '#86adff',
11 | light: '#507ed1',
12 | main: '#00529f',
13 | dark: '#002b70',
14 | darker: '#000044',
15 | contrastText: '#fff',
16 | rgba: 'rgba(0, 82, 159, 1)'
17 | },
18 | secondary: {
19 | lighter: '#99bffb',
20 | light: '#669ff9',
21 | main: '#337FF7',
22 | dark: '#0859d7',
23 | darker: '#063a8d',
24 | contrastText: '#fff',
25 | rgba: 'rgba(51, 127, 247, 1)'
26 | },
27 | background: {
28 | default: '#efeff8',
29 | paper: '#fff'
30 | },
31 | sideMenu: {
32 | bgColor: '#fff',
33 | color: '#00529f',
34 | hoverBgColor: '#DFF2FD',
35 | hoverTextColor: '#00529f',
36 | bgOpacity: '1',
37 | activeBgColor: '#00529f'
38 | }
39 | } as PaletteOptions)
40 |
41 | const lightBlueTheme: Theme = createTheme({
42 | palette,
43 | shape: { borderRadius: 8 },
44 | typography: generateTypography(palette),
45 | table,
46 | shadows: generateShadows(palette),
47 | customShadows: generateCustomShadows(palette)
48 | } as ThemeOptions)
49 |
50 | lightBlueTheme.components = componentsOverride(lightBlueTheme)
51 |
52 | export default lightBlueTheme
53 |
--------------------------------------------------------------------------------
/src/components/themes/orangeTheme.ts:
--------------------------------------------------------------------------------
1 | import { PaletteOptions, Theme, ThemeOptions, createTheme } from '@mui/material'
2 | import componentsOverride from './common/overrides'
3 | import generatePalette from './common/palette'
4 | import { generateTypography } from './common/typography'
5 | import { generateShadows, generateCustomShadows } from './common/shadows'
6 | import table from './common/table'
7 |
8 | const palette = generatePalette({
9 | primary: {
10 | lighter: '#b0b0b0',
11 | light: '#818181',
12 | main: '#555555',
13 | dark: '#2c2c2c',
14 | darker: '#000000',
15 | contrastText: '#fff',
16 | rgba: 'rgba(85, 85, 85, 1)'
17 | },
18 | secondary: {
19 | lighter: '#ffd170',
20 | light: '#ffa040',
21 | main: '#FF6F00',
22 | dark: '#c43e00',
23 | darker: '#8c0000',
24 | contrastText: '#fff',
25 | rgba: 'rgba(255, 111, 0)'
26 | },
27 | background: {
28 | default: '#fff',
29 | paper: '#fff'
30 | },
31 | sideMenu: {
32 | bgColor: '#000000d9',
33 | color: '#fff',
34 | hoverBgColor: 'rgba(200, 200, 200, 0.2)',
35 | hoverTextColor: '#fff',
36 | bgOpacity: '0.8',
37 | activeBgColor: '#FF6F00'
38 | }
39 | } as PaletteOptions)
40 |
41 | const orangeTheme: Theme = createTheme({
42 | palette,
43 | shape: { borderRadius: 8 },
44 | typography: generateTypography(palette),
45 | table,
46 | shadows: generateShadows(palette),
47 | customShadows: generateCustomShadows(palette)
48 | } as ThemeOptions)
49 |
50 | orangeTheme.components = componentsOverride(orangeTheme)
51 |
52 | export default orangeTheme
53 |
--------------------------------------------------------------------------------
/src/components/themes/redTheme.ts:
--------------------------------------------------------------------------------
1 | import { PaletteOptions, Theme, ThemeOptions, createTheme } from '@mui/material'
2 | import componentsOverride from './common/overrides'
3 | import generatePalette from './common/palette'
4 | import { generateTypography } from './common/typography'
5 | import { generateShadows, generateCustomShadows } from './common/shadows'
6 | import table from './common/table'
7 |
8 | const palette = generatePalette({
9 | primary: {
10 | lighter: '#9d9d9d',
11 | light: '#6f6f6f',
12 | main: '#444444',
13 | dark: '#1d1d1d',
14 | darker: '#000000',
15 | contrastText: '#fff',
16 | rgba: 'rgba(68, 68, 68, 1)'
17 | },
18 | secondary: {
19 | lighter: '#ff8d62',
20 | light: '#ff5a36',
21 | main: '#ff0000',
22 | dark: '#c20000',
23 | darker: '#890000',
24 | contrastText: '#fff',
25 | rgba: 'rgba(225, 25, 50, 1)'
26 | },
27 | background: {
28 | default: '#ddd8d3',
29 | paper: '#fff'
30 | },
31 | sideMenu: {
32 | bgColor: '#fff',
33 | color: '#444444',
34 | hoverBgColor: 'transparent',
35 | hoverTextColor: '#ff0000',
36 | bgOpacity: '0.8',
37 | activeBgColor: '#ff0000'
38 | }
39 | } as PaletteOptions)
40 |
41 | const redTheme: Theme = createTheme({
42 | palette,
43 | shape: { borderRadius: 8 },
44 | typography: generateTypography(palette),
45 | table,
46 | shadows: generateShadows(palette),
47 | customShadows: generateCustomShadows(palette)
48 | } as ThemeOptions)
49 |
50 | redTheme.components = componentsOverride(redTheme)
51 |
52 | export default redTheme
53 |
--------------------------------------------------------------------------------
/src/components/themes/vividOrangeTheme.ts:
--------------------------------------------------------------------------------
1 | import { Theme } from '@mui/material'
2 | import orangeTheme from './orangeTheme'
3 |
4 | const vividOrangeTheme: Theme = {
5 | ...orangeTheme,
6 | palette: {
7 | ...orangeTheme.palette,
8 | background: {
9 | default: '#eee',
10 | paper: '#fff'
11 | }
12 | }
13 | }
14 |
15 | export default vividOrangeTheme
16 |
--------------------------------------------------------------------------------
/src/components/types.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) TotalSoft.
2 | // This source code is licensed under the MIT license.
3 |
4 | // Available theme color options.
5 | export type Color =
6 | | 'primary'
7 | | 'secondary'
8 | | 'info'
9 | | 'success'
10 | | 'warning'
11 | | 'error'
12 | | 'rose'
13 | | 'default'
14 | | 'white'
15 | | 'dark'
16 | | 'transparent'
17 |
18 | // Available gradient color options.
19 | export type Gradient = Exclude
20 |
21 | // Available size options.
22 | export type Size = 'tiny' | 'small' | 'medium' | 'large'
23 |
--------------------------------------------------------------------------------
/src/components/utils/constants.ts:
--------------------------------------------------------------------------------
1 | export const sidebarWrapperHeight = Object.freeze('calc(100vh - 115px)')
2 | export const emptyArray: readonly unknown[] = Object.freeze([])
3 | export const emptyObject = Object.freeze({})
4 | export const emptyString = Object.freeze('')
5 | export const emptyFunction = Object.freeze(() => {})
6 |
--------------------------------------------------------------------------------
/src/components/utils/useDebouncedCallback.ts:
--------------------------------------------------------------------------------
1 | import debounce from 'lodash/debounce'
2 | import { useMemo, useRef } from 'react'
3 |
4 | const useDebouncedCallback = (callback: (...args: any[]) => any, debounceBy: number) => {
5 | const debouncedCallbackRef = useRef(undefined)
6 |
7 | const debouncedCallback = useMemo(() => {
8 | if (debounceBy) {
9 | if (debouncedCallbackRef?.current?.cancel && typeof debouncedCallbackRef.current.cancel === 'function')
10 | debouncedCallbackRef.current.cancel()
11 | const debounced = debounce(callback, debounceBy)
12 | debouncedCallbackRef.current = debounced
13 | return debounced
14 | }
15 | return callback
16 | }, [callback, debounceBy])
17 |
18 | return debouncedCallback
19 | }
20 |
21 | export default useDebouncedCallback
22 |
--------------------------------------------------------------------------------
/src/global.d.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) TotalSoft.
2 | // This source code is licensed under the MIT license.
3 |
4 | declare module '*.jpg'
5 | declare module '*.png'
6 | declare module '*.svg'
7 | declare module '*.mp3'
8 |
--------------------------------------------------------------------------------
/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // Copyright (c) TotalSoft.
2 | // This source code is licensed under the MIT license.
3 |
4 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
5 | // allows you to do things like:
6 | // expect(element).toHaveTextContent(/react/i)
7 | // learn more: https://github.com/testing-library/jest-dom
8 | import '@testing-library/jest-dom'
9 | import { TextEncoder } from 'util'
10 |
11 | global.TextEncoder = TextEncoder
12 |
--------------------------------------------------------------------------------
/src/stories/Introduction.stories.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react'
2 | import OrbitContainer from './_introduction/orbits/OrbitContainer'
3 | import AboutContainer from './_introduction/about/AboutContainer'
4 | import Grid from '@mui/material/Grid2'
5 | import type { Meta, StoryObj } from '@storybook/react'
6 |
7 | const LandingPage = () => {
8 | const [activeItem, setActiveItem] = useState(0)
9 |
10 | return (
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | )
20 | }
21 |
22 | const meta: Meta = {
23 | title: 'Introduction',
24 | component: LandingPage,
25 | tags: ['!autodocs'],
26 | parameters: {
27 | options: {
28 | showPanel: false
29 | }
30 | }
31 | } satisfies Meta
32 |
33 | export default meta
34 | type Story = StoryObj
35 |
36 | export const Introduction: Story = {
37 | render: () =>
38 | }
39 |
--------------------------------------------------------------------------------
/src/stories/_introduction/about/AboutContainer.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Title } from './AboutStyles'
3 | import Grid from '@mui/material/Grid2'
4 | import { orbits, homeData } from '../constants/orbits'
5 | import { Typography } from 'components'
6 |
7 | const AboutContainer = ({ activeItem = 0 }: any) => {
8 | const data = [homeData, ...orbits].find(o => o.id === activeItem)
9 | return (
10 |
11 |
12 | {data.name}
13 |
14 |
15 |
16 | {data.heading}
17 |
18 |
19 |
20 |
21 | {data.description}
22 |
23 |
24 |
25 | )
26 | }
27 |
28 | export default AboutContainer
29 |
--------------------------------------------------------------------------------
/src/stories/_introduction/about/AboutStyles.ts:
--------------------------------------------------------------------------------
1 | import styled from '@emotion/styled'
2 | import { Typography } from 'components'
3 |
4 | export const Title = styled(Typography)`
5 | font-size: 2.5rem;
6 | text-transform: uppercase;
7 | font-weight: 600;
8 | letter-spacing: -0.056rem;
9 |
10 | @media (min-width: 900px) {
11 | font-size: 3rem;
12 | margin-top: 150px;
13 | }
14 |
15 | @media (min-width: 768px) {
16 | font-size: 3rem;
17 | }
18 |
19 | @media (min-width: 1025px) {
20 | font-size: 5rem;
21 | }
22 | `
23 |
--------------------------------------------------------------------------------
/src/stories/_introduction/constants/orbits.ts:
--------------------------------------------------------------------------------
1 | export const orbits = [
2 | {
3 | id: 1,
4 | name: 'Material-UI',
5 | website: 'https://mui.com/',
6 | heading: 'The engine of our rocket.',
7 | description:
8 | 'This library represents our core, on top of which we design custom behaviors and styles. Besides that, it is one of our major benchmarks in terms of best development practices and conventions.',
9 | orbitColor: 'hsl(194, 48%, 49%)'
10 | },
11 | {
12 | id: 2,
13 | name: 'Github repository',
14 | website: 'https://github.com/osstotalsoft/rocket-ui-ts',
15 | heading: 'Feel free to join us as a rocket engineer anytime you want.',
16 | description:
17 | 'Have a look over our source code, create issues and contribute, so we can all have a safer and smoother flight.',
18 | orbitColor: 'hsl(33, 82%, 61%)'
19 | },
20 | {
21 | id: 3,
22 | name: 'npm Registry',
23 | website: 'https://www.npmjs.com/package/@totalsoft/rocket-ui',
24 | heading: 'Our rocket launch site.',
25 | description:
26 | 'We are building and publishing on npm public registry, the world`s largest software registry. Inside our scope, you can find codesandbox-style demos and source-code for all our rocket parts.',
27 | orbitColor: 'hsl(10, 63%, 51%)'
28 | }
29 | ]
30 |
31 | export const homeData = {
32 | id: 0,
33 | name: 'Rocket-UI',
34 | heading: 'Our modular, flexible and collaborative product.',
35 | description: 'An open-source and community-driven project to provide a consistent user interface across web applications.'
36 | }
37 |
38 | export default orbits
39 |
--------------------------------------------------------------------------------
/src/stories/_introduction/orbits/OrbitContainer.tsx:
--------------------------------------------------------------------------------
1 | import React, { useCallback } from 'react'
2 | import PropTypes from 'prop-types'
3 | import { Rocket, Container } from './OrbitStyles'
4 | import OrbitSwitch from './OrbitSwitch'
5 | import { orbits } from '../constants/orbits'
6 |
7 | const OrbitContainer = ({ setActiveItem }: any) => {
8 | const handleRocketHover = useCallback(() => setActiveItem(0), [setActiveItem])
9 |
10 | return (
11 |
12 |
13 | {orbits.map(orbit => (
14 |
15 | ))}
16 |
17 | )
18 | }
19 |
20 | OrbitContainer.propTypes = {
21 | setActiveItem: PropTypes.func.isRequired
22 | }
23 |
24 | export default OrbitContainer
25 |
--------------------------------------------------------------------------------
/src/stories/_introduction/orbits/OrbitSwitch.tsx:
--------------------------------------------------------------------------------
1 | import React, { useCallback } from 'react'
2 | import PropTypes from 'prop-types'
3 | import { MaterialOrbit, GitHubOrbit, BitOrbit } from './OrbitStyles'
4 |
5 | const OrbitSwitch = ({ data, setActiveItem }: any) => {
6 | const { id, website, orbitColor } = data
7 |
8 | const handleOrbitHover = useCallback(() => setActiveItem(id), [id, setActiveItem])
9 |
10 | const orbitProps = {
11 | href: website,
12 | orbitColor,
13 | target: '_blank',
14 | onMouseOver: handleOrbitHover
15 | }
16 |
17 | const orbitSwitch = () => {
18 | switch (data.id) {
19 | case 1:
20 | return
21 | case 2:
22 | return
23 | case 3:
24 | return
25 | }
26 | }
27 |
28 | return <>{orbitSwitch()}>
29 | }
30 |
31 | OrbitSwitch.propTypes = {
32 | data: PropTypes.object.isRequired,
33 | setActiveItem: PropTypes.func.isRequired
34 | }
35 |
36 | export default OrbitSwitch
37 |
--------------------------------------------------------------------------------
/src/stories/assets/audio/rain-ambient.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/osstotalsoft/rocket-ui-ts/80feca8180b7ce5d2767a81eaa53475aab999793/src/stories/assets/audio/rain-ambient.mp3
--------------------------------------------------------------------------------
/src/stories/assets/img/robot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/osstotalsoft/rocket-ui-ts/80feca8180b7ce5d2767a81eaa53475aab999793/src/stories/assets/img/robot.png
--------------------------------------------------------------------------------
/src/stories/assets/img/rocket.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/osstotalsoft/rocket-ui-ts/80feca8180b7ce5d2767a81eaa53475aab999793/src/stories/assets/img/rocket.png
--------------------------------------------------------------------------------
/src/stories/assets/img/satellite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/osstotalsoft/rocket-ui-ts/80feca8180b7ce5d2767a81eaa53475aab999793/src/stories/assets/img/satellite.png
--------------------------------------------------------------------------------
/src/stories/assets/img/spaceship.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/osstotalsoft/rocket-ui-ts/80feca8180b7ce5d2767a81eaa53475aab999793/src/stories/assets/img/spaceship.png
--------------------------------------------------------------------------------
/src/stories/assets/storyImg/code-brackets.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/stories/assets/storyImg/comments.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/stories/assets/storyImg/direction.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/stories/assets/storyImg/flow.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/stories/assets/storyImg/repo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/stories/buttons/Button/LoadingPreview.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) TotalSoft.
2 | // This source code is licensed under the MIT license.
3 |
4 | import React, { useCallback, useState } from 'react'
5 | import { Button } from '../../../components'
6 | import { Box, FormControlLabel, Switch } from '@mui/material'
7 |
8 | export const LoadingPreview: React.FunctionComponent = () => {
9 | const [loading, setLoading] = useState(false)
10 | const toggleLoading = useCallback(() => setLoading(current => !current), [])
11 |
12 | return (
13 | <>
14 | }
16 | label="Loading"
17 | sx={{ mb: '15px' }}
18 | />
19 |
20 |
23 |
26 |
29 |
30 | >
31 | )
32 | }
33 |
--------------------------------------------------------------------------------
/src/stories/buttons/Button/WithIconPreview.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) TotalSoft.
2 | // This source code is licensed under the MIT license.
3 |
4 | import React from 'react'
5 | import { Button } from '../../../components'
6 | import RocketIcon from '@mui/icons-material/Rocket'
7 |
8 | export const WithIconPreview: React.FunctionComponent = () => (
9 | <>
10 | } sx={{ mr: '15px' }}>
11 | start icon
12 |
13 | } sx={{ mr: '15px' }}>
14 | end icon
15 |
16 | } endIcon={} sx={{ mr: '15px' }}>
17 | both icons
18 |
19 |
22 |
25 |
28 |
31 |
34 | >
35 | )
36 |
--------------------------------------------------------------------------------
/src/stories/buttons/IconButton/LoadingPreview.tsx:
--------------------------------------------------------------------------------
1 | import React, { useCallback, useState } from 'react'
2 | import { Box, FormControlLabel, Switch } from '@mui/material'
3 | import RocketIcon from '@mui/icons-material/Rocket'
4 | import { IconButton } from 'components'
5 |
6 | export const LoadingPreview: React.FunctionComponent = () => {
7 | const [loading, setLoading] = useState(false)
8 | const toggleLoading = useCallback(() => setLoading(current => !current), [])
9 |
10 | return (
11 | <>
12 | }
14 | label="Loading"
15 | sx={{ mb: '15px' }}
16 | />
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | >
29 | )
30 | }
31 |
--------------------------------------------------------------------------------
/src/stories/buttons/IconButton/SizesPreview.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import Grid from '@mui/material/Grid2'
3 | import RocketIcon from '@mui/icons-material/Rocket'
4 | import { IconButton } from 'components'
5 |
6 | export const SizesPreview: React.FunctionComponent = () => (
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | )
32 |
--------------------------------------------------------------------------------
/src/stories/buttons/IconButton/TypesPreview.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import Grid from '@mui/material/Grid2'
3 | import { IconButton, IconButtonProps } from 'components'
4 |
5 | const sizeProps = { size: 'small', fontSize: 'medium' } satisfies IconButtonProps
6 |
7 | export const TypesPreview: React.FunctionComponent = () => (
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | )
44 |
--------------------------------------------------------------------------------
/src/stories/buttons/UploadButton/CustomIconsPreview.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import BrowserUpdatedIcon from '@mui/icons-material/BrowserUpdated'
3 | import ImageSearchIcon from '@mui/icons-material/ImageSearch'
4 | import DriveFolderUploadIcon from '@mui/icons-material/DriveFolderUpload'
5 | import { Box } from '@mui/system'
6 | import { UploadButton } from 'components'
7 |
8 | export const CustomIconsPreview = () => {
9 | return (
10 |
11 |
12 |
13 |
14 |
15 |
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/src/stories/buttons/UploadButton/IconPropsPreview.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Box } from '@mui/system'
3 | import { UploadButton } from 'components'
4 |
5 | export const IconPropsPreview = () => {
6 | return (
7 | <>
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | >
21 | )
22 | }
23 |
--------------------------------------------------------------------------------
/src/stories/buttons/UploadButton/InputTypesPreview.tsx:
--------------------------------------------------------------------------------
1 | import React, { useCallback, useState } from 'react'
2 | import { Box } from '@mui/material'
3 | import { Typography, UploadButton } from 'components'
4 |
5 | export const InputTypesPreview: React.FC = () => {
6 | const [error, setError] = useState()
7 | const handleError = useCallback((err: any) => setError(err), [])
8 | const handleChoice = useCallback(() => setError(undefined), [])
9 |
10 | return (
11 | <>
12 |
13 |
14 |
15 |
16 |
22 |
23 |
24 |
25 | {error?.message}
26 |
27 |
28 | {error?.files?.[0]?.name}
29 |
30 |
31 | >
32 | )
33 | }
34 |
--------------------------------------------------------------------------------
/src/stories/buttons/UploadButton/MobileCapturePreview.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Box } from '@mui/material'
3 | import { Typography, UploadButton } from 'components'
4 |
5 | export const MobileCapturePreview = () => {
6 | return (
7 | <>
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | Note these work better on mobile devices; If your device is a desktop computer, you'll likely get a typical
17 | file picker.
18 |
19 |
20 | >
21 | )
22 | }
23 |
--------------------------------------------------------------------------------
/src/stories/buttons/UploadButton/MultipleSelectionPreview.tsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useCallback } from 'react'
2 | import { head, join, prop, map } from 'ramda'
3 | import { Box } from '@mui/system'
4 | import { Typography, UploadButton } from 'components'
5 |
6 | export const MultipleSelectionPreview = () => {
7 | const [file, setFile] = useState('')
8 | const [files, setFiles] = useState('')
9 |
10 | const handleFileSelected = useCallback((files: FileList) => setFile(prop('name', head([...files])) as string), [])
11 | const handleFilesSelected = useCallback(
12 | (files: FileList) =>
13 | setFiles(
14 | join(
15 | '; ',
16 | map((file: File) => file.name, [...files])
17 | )
18 | ),
19 | []
20 | )
21 |
22 | return (
23 | <>
24 |
25 |
26 | {file}
27 |
28 |
29 |
30 | {files}
31 |
32 | >
33 | )
34 | }
35 |
--------------------------------------------------------------------------------
/src/stories/charts/DeprecatedStatsChart/BarPreview.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) TotalSoft.
2 | // This source code is licensed under the MIT license.
3 |
4 | import React from 'react'
5 | import { Button, DeprecatedStatsChart } from 'components'
6 | import AccessTime from '@mui/icons-material/AccessTime'
7 | import Grid from '@mui/material/Grid2'
8 | import { statsChartData, statsChartOptions } from './_mocks'
9 |
10 | const BarPreview = () => {
11 | return (
12 |
13 |
14 |
23 |
24 |
25 | Ok}
34 | iconColor="info"
35 | />
36 |
37 |
38 | )
39 | }
40 |
41 | export default BarPreview
42 |
--------------------------------------------------------------------------------
/src/stories/charts/DeprecatedStatsChart/LinePreview.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) TotalSoft.
2 | // This source code is licensed under the MIT license.
3 |
4 | import React from 'react'
5 | import { Button, DeprecatedStatsChart } from 'components'
6 | import AccessTime from '@mui/icons-material/AccessTime'
7 | import Grid from '@mui/material/Grid2'
8 | import { statsChartData, statsChartOptions } from './_mocks'
9 |
10 | const LinePreview = () => {
11 | return (
12 |
13 |
14 |
24 |
25 |
26 | Ok}
35 | />
36 |
37 |
38 | )
39 | }
40 |
41 | export default LinePreview
42 |
--------------------------------------------------------------------------------
/src/stories/dataDisplay/ExpandingText/DisplayPreview.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) TotalSoft.
2 | // This source code is licensed under the MIT license.
3 |
4 | import React from 'react'
5 | import Grid from '@mui/material/Grid2'
6 | import { ExpandingText, Typography } from 'components'
7 |
8 | const text =
9 | 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris viverra in neque non euismod. Nunc convallis ornare sem vel iaculis. Sed in condimentum sapien. Morbi viverra, dolor sed sollicitudin tristique, dui sem pretium odio, nec bibendum nibh velit vel turpis. Maecenas elit velit, molestie quis cursus eu, dignissim a elit. Etiam accumsan cursus ipsum, sit amet semper arcu faucibus sed. Donec aliquam fermentum ligula, a cursus lacus finibus non. Fusce id sollicitudin dui. Suspendisse malesuada lorem enim, at euismod neque tincidunt pellentesque.'
10 |
11 | export const DisplayPreview: React.FunctionComponent = () => (
12 |
13 |
14 |
15 | display: inline-block
16 |
17 |
18 |
19 |
20 |
21 | display: block
22 |
23 |
24 |
25 |
26 |
27 | display: flex; justify-content: flex-end
28 |
29 |
30 |
31 |
32 | )
33 |
--------------------------------------------------------------------------------
/src/stories/dataDisplay/FavIcon/FavIcon.stories.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import type { Meta, StoryObj } from '@storybook/react'
3 | import { FavIcon } from 'components'
4 |
5 | const meta: Meta = {
6 | title: 'Components/DataDisplay/FavIcon',
7 | component: FavIcon,
8 | argTypes: {
9 | favIconSource: {
10 | control: { type: 'radio' },
11 | options: ['/favicon.ico', '/faviconGlobe.ico', '/faviconReact.ico', '/faviconTS.ico']
12 | }
13 | },
14 | decorators: [
15 | (Story, {args}) => (
16 | <>
17 |
18 |
19 | >
20 | )
21 | ]
22 | } satisfies Meta
23 |
24 | export default meta
25 | type Story = StoryObj
26 |
27 | /**
28 | * Some predefined icon examples are provided through the documentation controls of the favIconSource prop
29 | */
30 |
31 | export const Default: Story = {
32 | args: {
33 | favIconSource: '/faviconGlobe.ico',
34 | defaultFavIcon: '/favicon.ico'
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/stories/dataDisplay/Typography/ColorsPreview.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) TotalSoft.
2 | // This source code is licensed under the MIT license.
3 |
4 | import { Typography } from 'components'
5 | import React from 'react'
6 |
7 | export const ColorsPreview: React.FunctionComponent = () => (
8 | <>
9 |
10 | Initial
11 |
12 |
13 | Error
14 |
15 |
16 | Primary
17 |
18 |
19 | Secondary
20 |
21 |
22 | Text Primary
23 |
24 |
25 | Text Secondary
26 |
27 | >
28 | )
29 |
--------------------------------------------------------------------------------
/src/stories/dataDisplay/Typography/ExtraStylingPreview.tsx:
--------------------------------------------------------------------------------
1 | // Copyright (c) TotalSoft.
2 | // This source code is licensed under the MIT license.
3 |
4 | import { Typography } from 'components'
5 | import React from 'react'
6 |
7 | export const ExtraStylingPreview: React.FunctionComponent = () => (
8 | <>
9 |
10 | Primary and bold - hover me to see a tooltip
11 |
12 |
13 | Secondary and italic
14 |
15 |
16 | Text primary and underline
17 |
18 |
19 | Text secondary and line-through
20 |
21 |
22 | Error and overline
23 |
24 | >
25 | )
26 |
--------------------------------------------------------------------------------
/src/stories/feedback/Dialog/ActionsPreview.tsx:
--------------------------------------------------------------------------------
1 | import Grid from '@mui/material/Grid2'
2 | import { Button, Dialog, TextField } from 'components'
3 | import React, { useCallback, useState } from 'react'
4 |
5 | const ActionsPreview = ({ button, ...props }: any) => {
6 | const [open, setOpen] = useState(false)
7 | const toggle = useCallback(() => setOpen(current => !current), [])
8 |
9 | return (
10 | <>
11 |
12 |