├── .circleci
└── config.yml
├── .github
└── ISSUE_TEMPLATE
│ ├── bug_report.md
│ ├── everything-else.md
│ └── feature_request.md
├── .gitignore
├── .npmrc
├── .nvmrc
├── .prettierignore
├── .storybook
├── main.js
├── manager.js
├── preview-head.html
└── preview.js
├── LICENSE
├── README.md
├── __snapshots__
├── chameleon-accordion.md
├── chameleon-accordions.md
├── chameleon-chart.md
├── chameleon-checkbox.md
├── chameleon-date.md
├── chameleon-input.md
├── chameleon-multiselect.md
├── chameleon-radio.md
├── chameleon-select.md
├── chameleon-sheet.md
└── chameleon-table.md
├── babel.config.json
├── docs
├── assets
│ └── chameleon.jpg
└── typography.md
├── karma.conf.js
├── lerna.json
├── netlify.toml
├── package.json
├── packages
├── accordions
│ ├── README.md
│ ├── __tests__
│ │ ├── chameleon-accordion.test.js
│ │ └── chameleon-accordions.test.js
│ ├── chameleon-accordion.js
│ ├── chameleon-accordions.js
│ ├── index.js
│ ├── package.json
│ └── src
│ │ ├── ChameleonAccordion.js
│ │ ├── ChameleonAccordionStyle.js
│ │ ├── ChameleonAccordions.js
│ │ └── ChameleonAccordionsStyle.js
├── alert
│ ├── README.md
│ ├── __tests__
│ │ └── chameleon-alert.test.js
│ ├── chameleon-alert.js
│ ├── index.js
│ ├── package.json
│ └── src
│ │ ├── ChameleonAlert.js
│ │ └── ChameleonAlertStyle.js
├── button
│ ├── README.md
│ ├── __tests__
│ │ └── chameleon-button.test.js
│ ├── chameleon-button.js
│ ├── index.js
│ ├── package.json
│ └── src
│ │ ├── ChameleonButton.js
│ │ └── ChameleonButtonStyle.js
├── card
│ ├── README.md
│ ├── __tests__
│ │ ├── chameleon-card-footer.test.js
│ │ ├── chameleon-card-header.test.js
│ │ ├── chameleon-card-image.test.js
│ │ └── chameleon-card.test.js
│ ├── chameleon-card-footer.js
│ ├── chameleon-card-header.js
│ ├── chameleon-card-image.js
│ ├── chameleon-card.js
│ ├── index.js
│ ├── package.json
│ └── src
│ │ ├── ChameleonCard.js
│ │ ├── ChameleonCardFooter.js
│ │ ├── ChameleonCardFooterStyle.js
│ │ ├── ChameleonCardHeader.js
│ │ ├── ChameleonCardHeaderStyle.js
│ │ ├── ChameleonCardImage.js
│ │ ├── ChameleonCardImageStyle.js
│ │ └── ChameleonCardStyle.js
├── chart
│ ├── README.md
│ ├── __tests__
│ │ └── chameleon-chart.test.js
│ ├── chameleon-chart.js
│ ├── index.js
│ ├── package.json
│ └── src
│ │ ├── ChameleonChart.js
│ │ └── ChameleonChartStyle.js
├── checkbox
│ ├── README.md
│ ├── __tests__
│ │ └── chameleon-checkbox.test.js
│ ├── chameleon-checkbox.js
│ ├── index.js
│ ├── package.json
│ └── src
│ │ ├── ChameleonCheckbox.js
│ │ └── ChameleonCheckboxStyle.js
├── chip
│ ├── README.md
│ ├── __tests__
│ │ └── chameleon-chip.test.js
│ ├── chameleon-chip.js
│ ├── index.js
│ ├── package.json
│ └── src
│ │ ├── ChameleonChip.js
│ │ └── ChameleonChipStyle.js
├── date
│ ├── README.md
│ ├── __tests__
│ │ └── chameleon-date.test.js
│ ├── chameleon-date.js
│ ├── index.js
│ ├── package.json
│ └── src
│ │ ├── ChameleonDate.js
│ │ └── ChameleonDateStyle.js
├── dialog
│ ├── README.md
│ ├── __tests__
│ │ └── chameleon-dialog.test.js
│ ├── chameleon-dialog.js
│ ├── index.js
│ ├── package.json
│ └── src
│ │ ├── ChameleonDialog.js
│ │ └── ChameleonDialogStyle.js
├── hero
│ ├── README.md
│ ├── __tests__
│ │ └── chameleon-hero.test.js
│ ├── chameleon-hero.js
│ ├── index.js
│ ├── package.json
│ └── src
│ │ ├── ChameleonHero.js
│ │ └── ChameleonHeroStyle.js
├── input
│ ├── README.md
│ ├── __tests__
│ │ └── chameleon-input.test.js
│ ├── chameleon-input.js
│ ├── index.js
│ ├── package.json
│ └── src
│ │ ├── ChameleonInput.js
│ │ └── ChameleonInputStyle.js
├── loader
│ ├── README.md
│ ├── __tests__
│ │ └── chameleon-loader.test.js
│ ├── chameleon-loader.js
│ ├── index.js
│ ├── package.json
│ └── src
│ │ ├── ChameleonLoader.js
│ │ ├── ChameleonLoaderEllipsisStyle.js
│ │ ├── ChameleonLoaderSpinnerStyle.js
│ │ └── ChameleonLoaderStyle.js
├── modal
│ ├── README.md
│ ├── __tests__
│ │ └── chameleon-modal.test.js
│ ├── chameleon-modal.js
│ ├── index.js
│ ├── package.json
│ └── src
│ │ ├── ChameleonModal.js
│ │ └── ChameleonModalStyle.js
├── multiselect
│ ├── README.md
│ ├── __tests__
│ │ └── chameleon-multiselect.test.js
│ ├── chameleon-multiselect.js
│ ├── index.js
│ ├── package.json
│ └── src
│ │ ├── ChameleonMultiselect.js
│ │ └── ChameleonMultiselectStyle.js
├── paginator
│ ├── README.md
│ ├── __tests__
│ │ └── chameleon-paginator.test.js
│ ├── chameleon-paginator.js
│ ├── index.js
│ ├── package.json
│ └── src
│ │ ├── ChameleonPaginator.js
│ │ └── ChameleonPaginatorStyle.js
├── progress-bar
│ ├── README.md
│ ├── __tests__
│ │ └── chameleon-progress-bar.test.js
│ ├── chameleon-progress-bar.js
│ ├── index.js
│ ├── package.json
│ └── src
│ │ ├── ChameleonProgressBar.js
│ │ └── ChameleonProgressBarStyle.js
├── radio
│ ├── README.md
│ ├── __tests__
│ │ └── chameleon-radio.test.js
│ ├── chameleon-radio.js
│ ├── index.js
│ ├── package.json
│ └── src
│ │ ├── ChameleonRadio.js
│ │ └── ChameleonRadioStyle.js
├── select
│ ├── README.md
│ ├── __tests__
│ │ └── chameleon-select.test.js
│ ├── chameleon-select.js
│ ├── index.js
│ ├── package.json
│ └── src
│ │ ├── ChameleonSelect.js
│ │ └── ChameleonSelectStyle.js
├── sheet
│ ├── README.md
│ ├── __tests__
│ │ ├── chameleon-sheet.test.js
│ │ └── sheet-content.test.js
│ ├── chameleon-sheet.js
│ ├── index.js
│ ├── package.json
│ ├── sheet-content.js
│ └── src
│ │ ├── ChameleonSheet.js
│ │ └── SheetContent.js
├── skeleton
│ ├── README.md
│ ├── __tests__
│ │ └── chameleon-skeleton.test.js
│ ├── chameleon-skeleton.js
│ ├── index.js
│ ├── package.json
│ └── src
│ │ ├── ChameleonSkeleton.js
│ │ └── ChameleonSkeletonStyle.js
├── switch
│ ├── README.md
│ ├── __tests__
│ │ └── chameleon-switch.test.js
│ ├── chameleon-switch.js
│ ├── index.js
│ ├── package.json
│ └── src
│ │ ├── ChameleonSwitch.js
│ │ └── ChameleonSwitchStyle.js
├── table
│ ├── README.md
│ ├── __tests__
│ │ └── chameleon-table.test.js
│ ├── chameleon-table.js
│ ├── index.js
│ ├── package.json
│ └── src
│ │ ├── ChameleonTable.js
│ │ └── ChameleonTableStyle.js
├── tabs
│ ├── README.md
│ ├── __tests__
│ │ └── chameleon-tabs.test.js
│ ├── chameleon-tab.js
│ ├── chameleon-tabs.js
│ ├── index.js
│ ├── package.json
│ └── src
│ │ ├── ChameleonTab.js
│ │ ├── ChameleonTabs.js
│ │ └── ChameleonTabsStyle.js
├── textarea
│ ├── README.md
│ ├── __tests__
│ │ └── chameleon-textarea.test.js
│ ├── chameleon-textarea.js
│ ├── index.js
│ ├── package.json
│ └── src
│ │ ├── ChameleonTextarea.js
│ │ └── ChameleonTextareaStyle.js
├── theme
│ ├── README.md
│ ├── base
│ │ └── index.js
│ └── package.json
├── timezone
│ ├── README.md
│ ├── __tests__
│ │ └── chameleon-timezone.test.js
│ ├── chameleon-timezone.js
│ ├── data
│ │ └── timezones.js
│ ├── index.js
│ ├── package.json
│ └── src
│ │ ├── ChameleonTimezone.js
│ │ └── ChameleonTimezoneStyle.js
└── toast
│ ├── README.md
│ ├── __tests__
│ └── chameleon-toast.test.js
│ ├── chameleon-toast.js
│ ├── index.js
│ ├── package.json
│ └── src
│ ├── ChameleonToast.js
│ └── ChameleonToastStyle.js
├── scripts
└── linker.js
└── yarn.lock
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | version: 2.1
2 | jobs:
3 | build:
4 | working_directory: ~/chameleon
5 | docker:
6 | - image: circleci/node:current-browsers
7 | environment:
8 | TZ: "America/Chicago"
9 | steps:
10 | - checkout
11 | - run:
12 | name: Install Dependencies
13 | command: |
14 | npm config set prefix '~/.npm-global'
15 | yarn setup
16 | - run: # run tests
17 | name: Test
18 | command: yarn test
19 | # COMMENTING THIS OUT UNTIL @open-wc/testing-karma GETS
20 | # UPDATED WITH THE LATEST ISTANBUL LIBRARIES
21 | # - run: # run coverage report
22 | # name: Code Coverage
23 | # command: |
24 | # yarn run generate:codecov
25 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: "[BUG]"
5 | labels: bug
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/everything-else.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Everything Else
3 | about: For everything else
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: "[FEATURE REQUEST]"
5 | labels: enhancement
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | npm-debug.log*
3 | lerna-debug.log*
4 | yarn-error.log*
5 |
6 | # Coverage directory used by tools like istanbul
7 | coverage
8 | *.lcov
9 |
10 | # Dependency directories
11 | node_modules/
12 |
13 | # System files
14 | .DS_Store
15 |
16 | # Generated distribution files
17 | lib/
18 | site/
19 |
20 | # Compiler Output
21 | /**/*.js.map
22 | /**/*.d.ts
23 | /**/*.d.ts.map
24 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | registry=https://registry.npmjs.org/
2 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | v12
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | docs/
2 | __snapshots__/
3 |
--------------------------------------------------------------------------------
/.storybook/main.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | stories: ["../README.md", "../docs/**/*.md", "../packages/*/README.md"],
3 | addons: [
4 | "storybook-prebuilt/addon-knobs/register.js",
5 | "storybook-prebuilt/addon-docs/register.js",
6 | "storybook-prebuilt/addon-viewport/register.js",
7 | "storybook-prebuilt/addon-backgrounds/register.js",
8 | ],
9 | esDevServer: {
10 | nodeResolve: true,
11 | watch: true,
12 | open: true,
13 | babel: true,
14 | },
15 | };
16 |
--------------------------------------------------------------------------------
/.storybook/manager.js:
--------------------------------------------------------------------------------
1 | import { addons } from "storybook-prebuilt/addons.js";
2 | import { create } from "storybook-prebuilt/theming/create.js";
3 |
4 | addons.setConfig({
5 | theme: create({
6 | base: "light",
7 | brandTitle: "Chameleon",
8 | brandUrl: "https://github.com/maritzstl/chameleon",
9 | }),
10 | });
11 |
--------------------------------------------------------------------------------
/.storybook/preview-head.html:
--------------------------------------------------------------------------------
1 |
18 |
--------------------------------------------------------------------------------
/.storybook/preview.js:
--------------------------------------------------------------------------------
1 | import { addParameters, setCustomElements } from "@open-wc/demoing-storybook";
2 |
3 | addParameters({
4 | docs: {
5 | iframeHeight: "300px",
6 | },
7 | });
8 |
9 | async function run() {
10 | // const customElements = await (
11 | // await fetch(new URL("../custom-elements.json", import.meta.url))
12 | // ).json();
13 |
14 | setCustomElements({});
15 | }
16 |
17 | run();
18 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Maritz Motivation Solutions, Inc.
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | [](https://app.netlify.com/sites/chameleon-design-system/deploys)
6 | [](https://circleci.com/gh/MaritzSTL/chameleon/tree/master)
7 | [](https://codecov.io/gh/MaritzSTL/chameleon)
8 |
9 | # Chameleon Web Components
10 |
11 | ```js script
12 | export default {
13 | title: "Intro|Chameleon Web Components",
14 | options: { selectedPanel: "storybookjs/docs/panel" },
15 | };
16 | ```
17 |
18 | Chameleon Web Components - A collection of lightweight, unidirectional, framework-agnostic elements based on the Chameleon Design System.
19 |
20 | ## Prerequisites
21 |
22 | The Chameleon project relies on some awesome tools in order to work properly. You'll want to have the following installed:
23 |
24 | - [Node.js](https://nodejs.org) - JavaScript runtime built on Chrome's V8 JavaScript Engine (this project uses v12.7.0)
25 | - [Git](https://git-scm.com/downloads) - Version control software for cloning this repository
26 | - [NVM (Node Version Manager)](https://github.com/nvm-sh/nvm) - A bash script to manage multiple active node.js versions
27 | - [Yarn](https://yarnpkg.com/lang/en/) - Package manager used for Yarn workspaces
28 |
29 | ## Setup
30 |
31 | **Note:** Please ensure you have all the prerequisite software installed before running any of these commands!
32 |
33 | To setup Chameleon for development, run the following in your folder of choice:
34 |
35 | ```bash
36 | git clone git@github.com:MaritzSTL/chameleon.git && cd chameleon && nvm use && yarn setup
37 | ```
38 |
39 | Chameleon uses storybook for development, so when you're ready to get going just run:
40 |
41 | ```bash
42 | yarn dev
43 | ```
44 |
45 | To build each element and package for distribution, run:
46 |
47 | ```bash
48 | yarn build
49 | ```
50 |
51 | If something looks wrong or you need to refresh your dependencies for whatever reason you can run:
52 |
53 | ```bash
54 | yarn clean
55 | ```
56 |
--------------------------------------------------------------------------------
/__snapshots__/chameleon-accordion.md:
--------------------------------------------------------------------------------
1 | # `chameleon-accordion`
2 |
3 | #### `renders !expanded correctly`
4 |
5 | ```html
6 |
16 |
17 |
18 |
19 |
20 |
21 | ```
22 |
23 | ```html
24 |
34 |
35 |
36 |
37 |
38 | ```
39 |
40 | #### `renders expanded correctly`
41 |
42 | ```html
43 |
53 |
54 |
55 |
56 |
57 |
58 | ```
59 |
60 | ```html
61 |
71 |
72 |
73 |
74 |
75 | ```
76 |
77 |
--------------------------------------------------------------------------------
/__snapshots__/chameleon-accordions.md:
--------------------------------------------------------------------------------
1 | # `chameleon-accordions`
2 |
3 | #### `renders any slotted content`
4 |
5 | ```html
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | ```
14 |
15 | ```html
16 |
17 |
18 |
19 | ```
20 |
21 |
--------------------------------------------------------------------------------
/__snapshots__/chameleon-chart.md:
--------------------------------------------------------------------------------
1 | # `chameleon-chart`
2 |
3 | #### `returns the arc chart type`
4 |
5 | ```html
6 |
13 |
14 |
21 |
22 |
23 | ```
24 |
25 |
--------------------------------------------------------------------------------
/__snapshots__/chameleon-checkbox.md:
--------------------------------------------------------------------------------
1 | # `chameleon-checkbox`
2 |
3 | #### `shows aria-invalid when invalid`
4 |
5 | ```html
6 |
12 |
13 |
14 |
15 | ```
16 |
17 | #### `shows name attribute`
18 |
19 | ```html
20 |
26 |
27 |
28 |
29 | ```
30 |
31 | #### `shows required attribute`
32 |
33 | ```html
34 |
41 |
42 |
43 |
44 | ```
45 |
46 | #### `shows readonly attribute`
47 |
48 | ```html
49 |
55 |
56 |
57 |
58 | ```
59 |
60 |
--------------------------------------------------------------------------------
/__snapshots__/chameleon-date.md:
--------------------------------------------------------------------------------
1 | # `chameleon-date`
2 |
3 | #### `prevIcon() returns default icon if none is supplied`
4 |
5 | ```html
6 |
11 |
12 |
13 |
14 |
20 |
21 |
22 | ```
23 |
24 | #### `prevIcon() returns the slot if one is provided`
25 |
26 | ```html
27 |
28 |
29 |
30 | ```
31 |
32 | #### `nextIcon() returns default icon if none is supplied`
33 |
34 | ```html
35 |
40 |
41 |
42 |
43 |
49 |
50 |
51 | ```
52 |
53 | #### `nextIcon() returns the slot if one is provided`
54 |
55 | ```html
56 |
57 |
58 |
59 | ```
60 |
61 |
--------------------------------------------------------------------------------
/__snapshots__/chameleon-input.md:
--------------------------------------------------------------------------------
1 | # `chameleon-input`
2 |
3 | #### `_inputEl renders number type`
4 |
5 | ```html
6 |
15 |
16 | ```
17 |
18 | #### `_inputEl renders default type`
19 |
20 | ```html
21 |
28 |
29 | ```
30 |
31 | #### `_inputEl renders disabled`
32 |
33 | ```html
34 |
42 |
43 | ```
44 |
45 | #### `_inputEl renders readonly`
46 |
47 | ```html
48 |
56 |
57 | ```
58 |
59 | #### `renders errorText`
60 |
61 | ```html
62 |
66 | chameleon
67 |
68 |
69 | ```
70 |
71 |
--------------------------------------------------------------------------------
/__snapshots__/chameleon-radio.md:
--------------------------------------------------------------------------------
1 | # `chameleon-radio`
2 |
3 | #### `shows aria-invalid when invalid`
4 |
5 | ```html
6 |
12 |
13 |
14 |
15 | ```
16 |
17 | #### `shows name attribute`
18 |
19 | ```html
20 |
26 |
27 |
28 |
29 | ```
30 |
31 | #### `shows disabled attribute`
32 |
33 | ```html
34 |
40 |
41 |
42 |
43 | ```
44 |
45 | #### `shows readonly attribute`
46 |
47 | ```html
48 |
54 |
55 |
56 |
57 | ```
58 |
59 |
--------------------------------------------------------------------------------
/__snapshots__/chameleon-sheet.md:
--------------------------------------------------------------------------------
1 | # `chameleon-sheet`
2 |
3 | #### `updatesSlot`
4 |
5 | ```html
6 |
11 |
12 | ```
13 |
14 |
--------------------------------------------------------------------------------
/__snapshots__/chameleon-table.md:
--------------------------------------------------------------------------------
1 | # `chameleon-table`
2 |
3 | #### `doesn't render pagination if .hidePagination is true`
4 |
5 | ```html
6 |
7 |
8 |
9 |
10 |
23 |
24 |
25 |
30 |
31 |
32 |
37 |
38 |
39 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | Row 1 - Field 1
51 |
52 |
53 | Row 1 - Field 2
54 |
55 |
56 | Row 1 - Field 3
57 |
58 |
59 | Row 1 - Field 4
60 |
61 |
62 |
63 |
64 |
68 |
69 | Row 2 - Field 1
70 |
71 |
72 | Row 2 - Field 2
73 |
74 |
75 | Row 2 - Field 3
76 |
77 |
78 | Row 2 - Field 4
79 |
80 |
81 |
85 |
86 |
87 |
88 |
89 | ```
90 |
91 | #### `renderColumnSort`
92 |
93 | ```html
94 |
100 |
101 | ```
102 |
103 | ## `icons`
104 |
105 | #### `renders chevronUpIcon`
106 |
107 | ```html
108 |
109 |
110 |
111 | ```
112 |
113 | #### `renders chevronDownIcon`
114 |
115 | ```html
116 |
117 |
118 |
119 | ```
120 |
121 |
--------------------------------------------------------------------------------
/babel.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | ["@babel/plugin-proposal-decorators", { "decoratorsBeforeExport": true }],
4 | "@babel/plugin-proposal-class-properties",
5 | "@babel/plugin-proposal-nullish-coalescing-operator",
6 | "@babel/plugin-proposal-optional-chaining"
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/docs/assets/chameleon.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MaritzSTL/chameleon/31383542fea4cd03d00fc690a5116f698c8bca65/docs/assets/chameleon.jpg
--------------------------------------------------------------------------------
/docs/typography.md:
--------------------------------------------------------------------------------
1 | # Typography
2 |
3 | ```js script
4 | export default {
5 | title: "Intro|Typography"
6 | };
7 | ```
8 |
9 | ## Typefaces
10 |
11 | ### Primary Typeface
12 |
13 | #### Lato
14 |
15 | ### Secondary Typeface
16 |
17 | #### Source Sans Pro
18 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | const { createDefaultConfig } = require("@open-wc/testing-karma");
2 | const merge = require("deepmerge");
3 |
4 | module.exports = (config) => {
5 | config.set(
6 | merge(createDefaultConfig(config), {
7 | files: [
8 | {
9 | pattern: config.grep ? config.grep : "packages/**/*.test.js",
10 | type: "module",
11 | },
12 | ],
13 | plugins: [require.resolve("@open-wc/karma-esm"), "karma-*"],
14 | frameworks: ["esm"],
15 | esm: {
16 | nodeResolve: true,
17 | babel: true,
18 | fileExtensions: [".js"],
19 | coverageExclude: ["packages/**/*.test.js"],
20 | },
21 | coverageIstanbulReporter: {
22 | thresholds: {
23 | emitWarning: true,
24 | global: {
25 | statements: 90,
26 | functions: 90,
27 | branches: 90,
28 | },
29 | },
30 | },
31 | })
32 | );
33 | return config;
34 | };
35 |
--------------------------------------------------------------------------------
/lerna.json:
--------------------------------------------------------------------------------
1 | {
2 | "packages": ["packages/*"],
3 | "version": "independent"
4 | }
5 |
--------------------------------------------------------------------------------
/netlify.toml:
--------------------------------------------------------------------------------
1 | [build]
2 | command = "yarn build-storybook"
3 | publish = "site/"
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "chameleon-ds",
3 | "version": "2.0.0",
4 | "description": "Chameleon Web Components - A collection of lightweight, unidirectional, framework-agnostic elements based on the Chameleon Design System",
5 | "scripts": {
6 | "prepare": "yarn build",
7 | "setup": "yarn install",
8 | "clean": "lerna clean --yes && del-cli node_modules coverage **/dist && git clean -fX",
9 | "test": "karma start",
10 | "test:debug": "karma start --coverage --log-level DEBUG",
11 | "test:watch": "karma start --auto-watch=true --single-run=false",
12 | "test:update-snapshots": "karma start --update-snapshots",
13 | "test:prune-snapshots": "karma start --prune-snapshots",
14 | "dev": "start-storybook -p 60000",
15 | "generate:codecov": "codecov",
16 | "generate:custom-element-file": "wca analyze 'packages/**/src/**/*.js' --outFile custom-elements.json",
17 | "build:ci": "lerna exec --concurrency 2 -- yarn run build",
18 | "build": "lerna exec yarn run build",
19 | "build-storybook": "del-cli docs/assets/storybook/ && build-storybook -o site",
20 | "bump-versions": "lerna version",
21 | "publish-packages": "lerna publish --yes from-package"
22 | },
23 | "repository": {
24 | "type": "git",
25 | "url": "git+https://github.com/MaritzSTL/chameleon.git"
26 | },
27 | "author": "Maritz Motivation Solutions, Inc.",
28 | "license": "MIT",
29 | "bugs": {
30 | "url": "https://github.com/MaritzSTL/chameleon/issues"
31 | },
32 | "homepage": "https://github.com/MaritzSTL/chameleon#readme",
33 | "private": true,
34 | "workspaces": [
35 | "packages/*"
36 | ],
37 | "devDependencies": {
38 | "@babel/cli": "^7.10.1",
39 | "@babel/core": "^7.10.2",
40 | "@babel/plugin-proposal-class-properties": "^7.10.1",
41 | "@babel/plugin-proposal-decorators": "^7.10.1",
42 | "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.1",
43 | "@babel/plugin-proposal-optional-chaining": "^7.10.1",
44 | "@babel/plugin-transform-react-jsx": "^7.10.1",
45 | "@open-wc/demoing-storybook": "^2.3.6",
46 | "@open-wc/karma-esm": "^2.13.21",
47 | "@open-wc/testing": "^2.5.8",
48 | "@open-wc/testing-karma": "^3.3.10",
49 | "@storybook/theming": "^5.3.19",
50 | "codecov": "^3.6.5",
51 | "deepmerge": "^4.2.2",
52 | "del-cli": "^3.0.0",
53 | "eslint": "^6.8.0",
54 | "husky": "^4.2.3",
55 | "lerna": "^3.20.2",
56 | "lit-html": "^1.2.1",
57 | "prettier": "^2.0.2",
58 | "pretty-quick": "^2.0.1",
59 | "react": "^16.3.0",
60 | "react-dom": "^16.3.0",
61 | "rollup": "^1.20.0",
62 | "sinon": "^7.5.0",
63 | "web-component-analyzer": "^1.0.3"
64 | },
65 | "husky": {
66 | "hooks": {
67 | "pre-commit": "pretty-quick --staged"
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/packages/accordions/__tests__/chameleon-accordions.test.js:
--------------------------------------------------------------------------------
1 | import { litFixture, html, expect } from "@open-wc/testing";
2 | import "../chameleon-accordion.js";
3 | import "../chameleon-accordions.js";
4 |
5 | const fixture = html`
6 |
7 |
8 |
9 |
10 | `;
11 |
12 | describe("chameleon-accordions", () => {
13 | let el;
14 |
15 | beforeEach(async () => {
16 | el = await litFixture(fixture);
17 | });
18 |
19 | it("renders any slotted content", () => {
20 | expect(el).dom.to.equalSnapshot({ ignoreAttributes: ["uid"] });
21 | expect(el).shadowDom.to.equalSnapshot();
22 | });
23 | it("registers accordions on `accordion-connected`", () => {
24 | expect(el.accordions.length).to.equal(2);
25 | });
26 | it("unregisters accordions on `accordion-disconnected`", async () => {
27 | const initialAccordions = Array.from(
28 | el.querySelectorAll("chameleon-accordion")
29 | ).map((acc) => acc.uid);
30 | const accordion = el.querySelector("chameleon-accordion");
31 | const removedUid = accordion.uid;
32 |
33 | accordion.disconnectedCallback();
34 |
35 | expect(initialAccordions.length).to.equal(2);
36 | expect(el.accordions.length).to.equal(1);
37 | expect(el.accordions.indexOf(removedUid)).to.equal(-1);
38 | });
39 | it("toggles targeted accordion on `toggle-accordion`", () => {
40 | const accordion = el.querySelector("chameleon-accordion");
41 | expect(accordion.expanded).to.equal(false);
42 | accordion.header.click();
43 | expect(accordion.expanded).to.equal(true);
44 | });
45 | it("closes all other registered accordions of targeted accordion is expanded", () => {
46 | const accordions = Array.from(el.querySelectorAll("chameleon-accordion"));
47 | accordions[0].expanded = true;
48 |
49 | expect(accordions[0].expanded).to.equal(true);
50 | expect(accordions[1].expanded).to.equal(false);
51 |
52 | accordions[1].header.click();
53 |
54 | expect(accordions[0].expanded).to.equal(false);
55 | expect(accordions[1].expanded).to.equal(true);
56 | });
57 | });
58 |
--------------------------------------------------------------------------------
/packages/accordions/chameleon-accordion.js:
--------------------------------------------------------------------------------
1 | import { ChameleonAccordion } from "./lib/ChameleonAccordion.js";
2 |
3 | customElements.define("chameleon-accordion", ChameleonAccordion);
4 |
--------------------------------------------------------------------------------
/packages/accordions/chameleon-accordions.js:
--------------------------------------------------------------------------------
1 | import { ChameleonAccordions } from "./lib/ChameleonAccordions.js";
2 |
3 | customElements.define("chameleon-accordions", ChameleonAccordions);
4 |
--------------------------------------------------------------------------------
/packages/accordions/index.js:
--------------------------------------------------------------------------------
1 | export { ChameleonAccordion } from "./lib/ChameleonAccordion.js";
2 | export { ChameleonAccordionStyle } from "./lib/ChameleonAccordionStyle.js";
3 | export { ChameleonAccordions } from "./lib/ChameleonAccordions.js";
4 | export { ChameleonAccordionsStyle } from "./lib/ChameleonAccordionsStyle.js";
5 |
--------------------------------------------------------------------------------
/packages/accordions/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@chameleon-ds/accordions",
3 | "version": "4.0.1",
4 | "description": "Chameleon accordions",
5 | "author": "Maritz Motivation Solutions, Inc.",
6 | "license": "MIT",
7 | "homepage": "https://github.com/MaritzSTL/chameleon/tree/master/packages/accordions#readme",
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/MaritzSTL/chameleon.git"
11 | },
12 | "main": "index.js",
13 | "module": "index.js",
14 | "files": [
15 | "chameleon-accordion.js",
16 | "chameleon-accordions.js",
17 | "/lib/"
18 | ],
19 | "scripts": {
20 | "test": "echo \"Error: run tests from root\" && exit 1",
21 | "build": "babel src --out-dir lib --config-file ../../babel.config.json"
22 | },
23 | "bugs": {
24 | "url": "https://github.com/MaritzSTL/chameleon/issues"
25 | },
26 | "dependencies": {
27 | "lit-element": "^2.2.1"
28 | },
29 | "publishConfig": {
30 | "access": "public"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/packages/accordions/src/ChameleonAccordionStyle.js:
--------------------------------------------------------------------------------
1 | import { css } from "lit-element";
2 |
3 | export const ChameleonAccordionStyle = css`
4 | :host {
5 | display: block;
6 | }
7 |
8 | .header {
9 | background-color: var(--accordion-background-color, #ffffff);
10 | border: 1px solid var(--color-gray-dark, #9fa4a8);
11 | border-radius: var(--border-radius, 0.5rem);
12 | cursor: pointer;
13 | display: flex;
14 | flex-direction: column;
15 | padding: 13px;
16 | }
17 |
18 | :host([expanded]) .header {
19 | border-radius: var(--border-radius, 0.5rem) var(--border-radius, 0.5rem) 0 0;
20 | }
21 |
22 | .header-toggle {
23 | align-items: center;
24 | display: flex;
25 | }
26 |
27 | .header-toggle chameleon-button {
28 | margin: 0 15px;
29 | }
30 |
31 | .panel {
32 | border: 1px solid var(--color-gray-dark, #9fa4a8);
33 | border-radius: 0 0 var(--border-radius, 0.5rem) var(--border-radius, 0.5rem);
34 | border-top: none;
35 | padding: 13px;
36 | }
37 |
38 | .panel.collapsed {
39 | display: none;
40 | }
41 |
42 | .panel.expanded {
43 | display: block;
44 | }
45 |
46 | .toggle-icon {
47 | margin: 0 30px 0 17px;
48 | }
49 |
50 | .toggle-icon svg {
51 | transition: transform 0.2s ease-in-out;
52 | }
53 |
54 | .toggle-icon.rotate svg {
55 | transform: rotate(90deg);
56 | }
57 | `;
58 |
--------------------------------------------------------------------------------
/packages/accordions/src/ChameleonAccordions.js:
--------------------------------------------------------------------------------
1 | import { LitElement, property, html } from "lit-element";
2 | import { ChameleonAccordionsStyle } from "./ChameleonAccordionsStyle.js";
3 |
4 | export class ChameleonAccordions extends LitElement {
5 | /**
6 | * Lifecycle Methods
7 | */
8 | constructor() {
9 | super();
10 | this.addEventListener("accordion-connected", this._registerAccordion);
11 | this.addEventListener("toggle-accordion", this._handleToggle);
12 | this.addEventListener("accordion-disconnected", this._unregisterAccordion);
13 | }
14 | /**
15 | * Properties
16 | */
17 | @property({ type: Array }) accordions = [];
18 |
19 | /**
20 | * Styles
21 | */
22 | static styles = [ChameleonAccordionsStyle];
23 |
24 | /**
25 | * Template
26 | */
27 | render() {
28 | return html` `;
29 | }
30 |
31 | _registerAccordion(e) {
32 | this.accordions = [...this.accordions, e.target];
33 | e.detail.connected = true;
34 | e.stopPropagation();
35 | }
36 |
37 | _unregisterAccordion(e) {
38 | this.accordions = [
39 | ...this.accordions.filter((accordion) => accordion.uid !== e.target.uid),
40 | ];
41 | e.stopPropagation();
42 | }
43 |
44 | _handleToggle(e) {
45 | const accordionToToggle = this.accordions.find(
46 | (accordion) => accordion.uid === e.target.uid
47 | );
48 | accordionToToggle.expanded = !accordionToToggle.expanded;
49 |
50 | // if opening one, close all others
51 | if (accordionToToggle.expanded) {
52 | this.accordions
53 | .filter((accordion) => accordion !== accordionToToggle)
54 | .forEach((accordion) => (accordion.expanded = false));
55 | }
56 |
57 | e.stopPropagation();
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/packages/accordions/src/ChameleonAccordionsStyle.js:
--------------------------------------------------------------------------------
1 | import { css } from "lit-element";
2 |
3 | export const ChameleonAccordionsStyle = css`
4 | :host {
5 | display: block;
6 | width: var(--accordion-width, 100%);
7 | font-family: var(--font-family, sans-serif);
8 | }
9 |
10 | ::slotted(chameleon-accordion:not(:last-of-type)) {
11 | margin-bottom: 25px;
12 | }
13 | `;
14 |
--------------------------------------------------------------------------------
/packages/alert/README.md:
--------------------------------------------------------------------------------
1 | # Chameleon Alert
2 |
3 | ```js script
4 | import { html } from "@open-wc/demoing-storybook";
5 | import "./chameleon-alert.js";
6 |
7 | export default {
8 | title: "Components|Feedback/Alert",
9 | component: "chameleon-alert",
10 | options: { selectedPanel: "storybookjs/docs/panel" },
11 | };
12 | ```
13 |
14 | ## Examples
15 |
16 | ### Default
17 |
18 | ```js preview-story
19 | export const Default = () => html`
20 |
21 | Riverside cleanup will meet at the Gateway Arch on Saturday!
22 |
23 | `;
24 | ```
25 |
--------------------------------------------------------------------------------
/packages/alert/__tests__/chameleon-alert.test.js:
--------------------------------------------------------------------------------
1 | import { litFixture, html, expect } from "@open-wc/testing";
2 | import "../chameleon-alert.js";
3 |
4 | const fixture = html` `;
5 |
6 | describe("chameleon-alert", () => {
7 | let element;
8 |
9 | beforeEach(async () => {
10 | element = await litFixture(fixture);
11 | });
12 |
13 | it("renders", () => {
14 | expect(Boolean(element.shadowRoot)).to.equal(true);
15 | });
16 |
17 | // TODO: this test passes when it shouldn't
18 | xit("handle close removes the element from the DOM", async () => {
19 | // element.handleClose();
20 | // element.requestUpdate();
21 | // await element.updateComplete;
22 |
23 | expect(element).lightDom.to.equal("");
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/packages/alert/chameleon-alert.js:
--------------------------------------------------------------------------------
1 | import { ChameleonAlert } from "./lib/ChameleonAlert.js";
2 |
3 | customElements.define("chameleon-alert", ChameleonAlert);
4 |
--------------------------------------------------------------------------------
/packages/alert/index.js:
--------------------------------------------------------------------------------
1 | export { ChameleonAlert } from "./lib/ChameleonAlert.js";
2 | export { ChameleonAlertStyle } from "./lib/ChameleonAlertStyle.js";
3 |
--------------------------------------------------------------------------------
/packages/alert/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@chameleon-ds/alert",
3 | "version": "2.0.1",
4 | "description": "Chameleon alert",
5 | "author": "Maritz Motivation Solutions, Inc.",
6 | "license": "MIT",
7 | "homepage": "https://github.com/MaritzSTL/chameleon/tree/master/packages/alert#readme",
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/MaritzSTL/chameleon.git"
11 | },
12 | "main": "index.js",
13 | "module": "index.js",
14 | "files": [
15 | "chameleon-alert.js",
16 | "/lib/"
17 | ],
18 | "scripts": {
19 | "test": "echo \"Error: run tests from root\" && exit 1",
20 | "build": "babel src --out-dir lib --config-file ../../babel.config.json"
21 | },
22 | "bugs": {
23 | "url": "https://github.com/MaritzSTL/chameleon/issues"
24 | },
25 | "dependencies": {
26 | "lit-element": "^2.2.1"
27 | },
28 | "publishConfig": {
29 | "access": "public"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/packages/alert/src/ChameleonAlert.js:
--------------------------------------------------------------------------------
1 | import { LitElement, html, svg } from "lit-element";
2 | import { ChameleonAlertStyle } from "./ChameleonAlertStyle";
3 |
4 | export class ChameleonAlert extends LitElement {
5 | /**
6 | * Styles
7 | */
8 | static styles = [ChameleonAlertStyle];
9 |
10 | /**
11 | * Template
12 | */
13 | render() {
14 | return html`
15 | ${this.alertIcon}
16 |
17 |
18 | ${this.closeIcon}
19 |
20 | `;
21 | }
22 |
23 | handleClose() {
24 | this.remove();
25 | }
26 |
27 | get alertIcon() {
28 | return svg`
29 |
40 |
41 |
42 |
43 |
44 |
45 | `;
46 | }
47 |
48 | get closeIcon() {
49 | return svg`
50 |
60 |
61 |
62 |
63 | `;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/packages/alert/src/ChameleonAlertStyle.js:
--------------------------------------------------------------------------------
1 | import { css } from "lit-element";
2 |
3 | export const ChameleonAlertStyle = css`
4 | :host {
5 | align-items: center;
6 | background-color: var(--color-error-lightest, #f1d1d0);
7 | border: 1px solid var(--color-error, #bc1c16);
8 | border-radius: var(--border-radius-input, 0.313rem);
9 | color: var(--color-error, #bc1c16);
10 | display: inline-flex;
11 | padding: 14px 10px;
12 | }
13 |
14 | .closebtn {
15 | color: var(--color-error, #bc1c16);
16 | cursor: pointer;
17 | display: flex;
18 | margin: 0px 0px 0px 15px;
19 | }
20 |
21 | .icon {
22 | height: 24px;
23 | margin: 0px 15px 0px 0px;
24 | }
25 |
26 | .message {
27 | font-size: var(--font-size-input, 0.938rem);
28 | font-weight: 600;
29 | }
30 | `;
31 |
--------------------------------------------------------------------------------
/packages/button/README.md:
--------------------------------------------------------------------------------
1 | # Chameleon Button
2 |
3 | ```js script
4 | import { html, svg } from "lit-html";
5 | import "./chameleon-button.js";
6 |
7 | export default {
8 | title: "Components|Buttons/Button",
9 | component: "chameleon-button",
10 | options: { selectedPanel: "storybookjs/docs/panel" },
11 | };
12 | ```
13 |
14 | ## Properties
15 |
16 | | Property Name | Type(s) | Default Value | Description |
17 | | ------------- | ------- | ------------- | ----------------------------------------------------------- |
18 | | `disabled` | Boolean | `false` | Whether or not the button is disabled |
19 | | `loading` | Boolean | `false` | When true, a loading spinner will display |
20 | | `theme` | String | `"primary"` | The theme of the button ("primary", "secondary", or "text") |
21 | | `icon-left` | Boolean | `false` | When true, will display a left icon |
22 | | `icon-right` | Boolean | `false` | When true, will display a right icon |
23 | | `icon-only` | Boolean | `false` | When true, will display only an icon |
24 | | `href` | String | `null` | The link href |
25 | | `target` | String | `"_top"` | The link target |
26 |
27 | ## Examples
28 |
29 | ### Default
30 |
31 | ```js preview-story
32 | export const Default = () => html`Login `;
33 | ```
34 |
35 | ### Secondary Theme
36 |
37 | ```js preview-story
38 | export const SecondaryTheme = () =>
39 | html`Login `;
40 | ```
41 |
42 | ### Text Theme
43 |
44 | ```js preview-story
45 | export const TextTheme = () =>
46 | html`Login `;
47 | ```
48 |
49 | ### Text with Icon
50 |
51 | ```js preview-story
52 | const heartIconLeft = svg` `;
53 |
54 | export const TextWithIcon = () =>
55 | html`${heartIconLeft} Love `;
58 | ```
59 |
60 | ### Icon Only
61 |
62 | ```js preview-story
63 | const heartIcon = svg` `;
64 |
65 | export const IconOnly = () =>
66 | html`${heartIcon} `;
69 | ```
70 |
--------------------------------------------------------------------------------
/packages/button/__tests__/chameleon-button.test.js:
--------------------------------------------------------------------------------
1 | import { fixture, html, expect } from "@open-wc/testing";
2 | import "../chameleon-button.js";
3 |
4 | describe("chameleon-button", () => {
5 | it("renders", async () => {
6 | const el = await fixture(html` `);
7 | expect(Boolean(el.shadowRoot)).to.equal(true);
8 | });
9 |
10 | it("renders as a button when no href is set", async () => {
11 | const el = await fixture(html` `);
12 | expect(Boolean(el.shadowRoot.querySelector(":host > button"))).to.equal(
13 | true
14 | );
15 | expect(Boolean(el.shadowRoot.querySelector(":host > a"))).to.equal(false);
16 | });
17 |
18 | it("renders as a link when an href is set", async () => {
19 | const el = await fixture(
20 | html`
21 |
24 | `
25 | );
26 |
27 | expect(Boolean(el.shadowRoot.querySelector(":host > a"))).to.equal(true);
28 | expect(Boolean(el.shadowRoot.querySelector(":host > button"))).to.equal(
29 | false
30 | );
31 | });
32 |
33 | it("anchor sets target to _top when target is missing", async () => {
34 | const el = await fixture(
35 | html`
36 |
39 | `
40 | );
41 |
42 | expect(
43 | Boolean(el.shadowRoot.querySelector(":host > a[target='_top']"))
44 | ).to.equal(true);
45 | });
46 |
47 | it("anchor sets target to _top when target set to _top", async () => {
48 | const el = await fixture(
49 | html`
50 |
54 | `
55 | );
56 |
57 | expect(
58 | Boolean(el.shadowRoot.querySelector(":host > a[target='_top']"))
59 | ).to.equal(true);
60 | });
61 |
62 | it("anchor sets target to _blank when target set to _blank", async () => {
63 | const el = await fixture(
64 | html`
65 |
69 | `
70 | );
71 |
72 | expect(
73 | Boolean(el.shadowRoot.querySelector(":host > a[target='_blank']"))
74 | ).to.equal(true);
75 | });
76 | });
77 |
--------------------------------------------------------------------------------
/packages/button/chameleon-button.js:
--------------------------------------------------------------------------------
1 | import { ChameleonButton } from "./lib/ChameleonButton.js";
2 |
3 | customElements.define("chameleon-button", ChameleonButton);
4 |
--------------------------------------------------------------------------------
/packages/button/index.js:
--------------------------------------------------------------------------------
1 | export { ChameleonButton } from "./lib/ChameleonButton.js";
2 | export { ChameleonButtonStyle } from "./lib/ChameleonButtonStyle.js";
3 |
--------------------------------------------------------------------------------
/packages/button/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@chameleon-ds/button",
3 | "version": "2.0.1",
4 | "description": "Chameleon button",
5 | "author": "Maritz Motivation Solutions, Inc.",
6 | "license": "MIT",
7 | "homepage": "https://github.com/MaritzSTL/chameleon/tree/master/packages/button#readme",
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/MaritzSTL/chameleon.git"
11 | },
12 | "main": "index.js",
13 | "module": "index.js",
14 | "files": [
15 | "chameleon-button.js",
16 | "/lib/"
17 | ],
18 | "scripts": {
19 | "test": "echo \"Error: run tests from root\" && exit 1",
20 | "build": "babel src --out-dir lib --config-file ../../babel.config.json"
21 | },
22 | "bugs": {
23 | "url": "https://github.com/MaritzSTL/chameleon/issues"
24 | },
25 | "dependencies": {
26 | "@chameleon-ds/loader": "^2.0.1",
27 | "lit-element": "^2.2.1"
28 | },
29 | "publishConfig": {
30 | "access": "public"
31 | },
32 | "gitHead": "0f8abecfe290971a220b969fc4d82fba4f6869ad"
33 | }
34 |
--------------------------------------------------------------------------------
/packages/button/src/ChameleonButton.js:
--------------------------------------------------------------------------------
1 | import { LitElement, html, property } from "lit-element";
2 | import { nothing } from "lit-html";
3 | import { classMap } from "lit-html/directives/class-map";
4 | import { ChameleonButtonStyle } from "./ChameleonButtonStyle.js";
5 | import "@chameleon-ds/loader/chameleon-loader.js";
6 |
7 | export class ChameleonButton extends LitElement {
8 | /**
9 | * Properties
10 | */
11 | @property({ type: Boolean, reflect: true })
12 | disabled = false;
13 |
14 | @property({ type: Boolean, reflect: true })
15 | loading = false;
16 |
17 | @property({ type: String, reflect: true })
18 | theme = "primary";
19 |
20 | // Element has a left icon
21 | @property({ type: Boolean, reflect: true })
22 | "icon-left" = false;
23 |
24 | // Element has a right icon
25 | @property({ type: Boolean, reflect: true })
26 | "icon-right" = false;
27 |
28 | // Element has a icon only
29 | @property({ type: Boolean, reflect: true })
30 | "icon-only" = false;
31 |
32 | // Element has an href
33 | @property({ type: String, reflect: true })
34 | href = null;
35 |
36 | // Element should honor the target
37 | @property({ type: String, reflect: true })
38 | target = "_top";
39 |
40 | /**
41 | * Styles
42 | */
43 | static styles = [ChameleonButtonStyle];
44 |
45 | /**
46 | * Template
47 | */
48 | render() {
49 | return html`
50 | ${this.href && !this.disabled
51 | ? html`
52 |
53 | ${this.renderButton()}
54 |
55 | `
56 | : html` ${this.renderButton()} `}
57 | `;
58 | }
59 |
60 | renderButton() {
61 | return html`
62 |
66 | ${this.loading
67 | ? html`
68 |
69 |
70 |
71 | `
72 | : nothing}
73 |
74 |
75 |
76 |
77 |
78 | `;
79 | }
80 |
81 | getRel() {
82 | return this.target === "_blank" ? `noopener noreferrer` : ``;
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/packages/button/src/ChameleonButtonStyle.js:
--------------------------------------------------------------------------------
1 | import { css } from "lit-element";
2 |
3 | export const ChameleonButtonStyle = css`
4 | :host {
5 | --button-border-color: var(--color-primary, #2c6fb7);
6 | --button-hover-color: var(--color-primary-dark, #004587);
7 | --button-hover-text-color: var(--color-surface, #ffffff);
8 | --button-text-color: var(--color-primary, #2c6fb7);
9 | display: inline-flex;
10 | height: var(--button-height, 40px);
11 | }
12 |
13 | :host([full-width]) {
14 | width: 100%;
15 | }
16 |
17 | :host([full-width]) a,
18 | :host([full-width]) button {
19 | width: 100%;
20 | }
21 |
22 | :host([icon-only]),
23 | :host([theme="text"]) {
24 | --button-height: auto;
25 | }
26 |
27 | :host([icon-only]) button,
28 | :host([icon-left]) button,
29 | :host([icon-right]) button {
30 | padding: 0;
31 | }
32 |
33 | :host([disabled]) {
34 | pointer-events: none;
35 | }
36 |
37 | a {
38 | display: inline-block;
39 | text-decoration: none;
40 | }
41 |
42 | button[disabled] {
43 | background-color: var(--color-gray-lightest, #e1e3e4);
44 | border-color: var(--color-gray-lightest, #e1e3e4);
45 | color: var(--color-gray-darkest, #6c737a);
46 | }
47 |
48 | button {
49 | align-items: center;
50 | background-color: var(--color-primary, #2c6fb7);
51 | border-radius: var(--border-radius-input, 0.313rem);
52 | border: 1px solid var(--button-border-color);
53 | color: var(--color-surface, #ffffff);
54 | cursor: pointer;
55 | display: flex;
56 | font-family: var(--font-family, sans-serif);
57 | font-weight: var(--font-weight, 600);
58 | font-size: var(--font-size-paragraph-medium, 0.938rem);
59 | justify-content: center;
60 | letter-spacing: var(--font-letter-spacing, 0.018rem);
61 | line-height: 1;
62 | padding: var(--button-padding, 0.75rem 1.375rem);
63 | position: relative;
64 | transition: background-color 150ms linear, color 150ms linear,
65 | border 150ms linear;
66 | height: 100%;
67 | width: 100%;
68 | }
69 |
70 | button:hover {
71 | background-color: var(--button-hover-color);
72 | border-color: var(--button-hover-color);
73 | }
74 |
75 | .secondary {
76 | background-color: unset;
77 | color: var(--button-text-color);
78 | }
79 |
80 | .secondary:hover {
81 | color: var(--button-hover-text-color);
82 | }
83 |
84 | .text {
85 | background-color: transparent;
86 | color: var(--color-primary, #2c6fb7);
87 | text-decoration: underline;
88 | align-self: center;
89 | padding: 0;
90 | border: none;
91 | }
92 |
93 | .text:hover {
94 | background-color: transparent;
95 | color: var(--color-primary-dark, #004587);
96 | }
97 |
98 | button[disabled].text {
99 | background-color: transparent;
100 | }
101 |
102 | ::slotted([slot="icon-left"]) {
103 | margin-right: 0.1875rem;
104 | }
105 |
106 | ::slotted([slot="icon-right"]) {
107 | margin-left: 0.1875rem;
108 | }
109 |
110 | ::slotted(svg) {
111 | height: 1.5rem;
112 | width: 1.5rem;
113 | }
114 |
115 | slot[name="icon-loading"] > * {
116 | height: calc(100% - 1rem);
117 | margin: 0.5rem 0;
118 | position: absolute;
119 | top: 0;
120 | width: 25%;
121 | }
122 |
123 | /* If the loading icon is rendered, hide the rest of the button content */
124 | slot[name="icon-loading"] ~ * {
125 | visibility: hidden;
126 | }
127 | `;
128 |
--------------------------------------------------------------------------------
/packages/card/__tests__/chameleon-card-footer.test.js:
--------------------------------------------------------------------------------
1 | import { litFixture, html, expect } from "@open-wc/testing";
2 | import "../chameleon-card-footer.js";
3 |
4 | describe("chameleon-card-footer", () => {
5 | it("renders", async () => {
6 | const el = await litFixture(html`
7 |
8 | `);
9 | expect(Boolean(el.shadowRoot)).to.equal(true);
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/packages/card/__tests__/chameleon-card-header.test.js:
--------------------------------------------------------------------------------
1 | import { litFixture, html, expect } from "@open-wc/testing";
2 | import "../chameleon-card-header.js";
3 |
4 | const fixture = html` `;
5 |
6 | describe("chameleon-card-header", () => {
7 | let element;
8 |
9 | beforeEach(async () => {
10 | element = await litFixture(fixture);
11 | });
12 |
13 | it("renders", () => {
14 | expect(Boolean(element.shadowRoot)).to.equal(true);
15 | });
16 |
17 | it("renders subtitle", async () => {
18 | element.subtitle = "chameleon";
19 | element.requestUpdate();
20 | await element.updateComplete;
21 |
22 | expect(element).shadowDom.to.equal("chameleon ");
23 | });
24 |
25 | it("renders title", async () => {
26 | element.title = "chameleon";
27 | element.requestUpdate();
28 | await element.updateComplete;
29 |
30 | expect(element).shadowDom.to.equal("chameleon ");
31 | });
32 | });
33 |
--------------------------------------------------------------------------------
/packages/card/__tests__/chameleon-card-image.test.js:
--------------------------------------------------------------------------------
1 | import "../chameleon-card-image.js";
2 | import { fixture, html, expect } from "@open-wc/testing";
3 |
4 | describe("chameleon-card-image", () => {
5 | it("renders", async () => {
6 | const el = await fixture(html`
7 |
8 | `);
9 | expect(Boolean(el.shadowRoot)).to.equal(true);
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/packages/card/__tests__/chameleon-card.test.js:
--------------------------------------------------------------------------------
1 | import { litFixture, html, expect } from "@open-wc/testing";
2 | import "../chameleon-card.js";
3 |
4 | describe("chameleon-card", () => {
5 | it("renders", async () => {
6 | const element = await litFixture(html` `);
7 |
8 | expect(Boolean(element.shadowRoot)).to.equal(true);
9 | });
10 |
11 | it("should set default accentColor", async () => {
12 | const element = await litFixture(
13 | html` `
14 | );
15 |
16 | expect(element.style.borderTop).to.equal(
17 | "7px solid var(--color-primary, #2c6fb7)"
18 | );
19 | });
20 |
21 | it("should set accentColor", async () => {
22 | const element = await litFixture(
23 | html` `
24 | );
25 |
26 | expect(element.style.borderTop).to.equal("7px solid green");
27 | });
28 | });
29 |
--------------------------------------------------------------------------------
/packages/card/chameleon-card-footer.js:
--------------------------------------------------------------------------------
1 | import { ChameleonCardFooter } from "./lib/ChameleonCardFooter.js";
2 |
3 | customElements.define("chameleon-card-footer", ChameleonCardFooter);
4 |
--------------------------------------------------------------------------------
/packages/card/chameleon-card-header.js:
--------------------------------------------------------------------------------
1 | import { ChameleonCardHeader } from "./lib/ChameleonCardHeader.js";
2 |
3 | customElements.define("chameleon-card-header", ChameleonCardHeader);
4 |
--------------------------------------------------------------------------------
/packages/card/chameleon-card-image.js:
--------------------------------------------------------------------------------
1 | import { ChameleonCardImage } from "./lib/ChameleonCardImage.js";
2 |
3 | customElements.define("chameleon-card-image", ChameleonCardImage);
4 |
--------------------------------------------------------------------------------
/packages/card/chameleon-card.js:
--------------------------------------------------------------------------------
1 | import { ChameleonCard } from "./lib/ChameleonCard.js";
2 |
3 | customElements.define("chameleon-card", ChameleonCard);
4 |
--------------------------------------------------------------------------------
/packages/card/index.js:
--------------------------------------------------------------------------------
1 | export { ChameleonCard } from "./lib/ChameleonCard.js";
2 | export { ChameleonCardFooter } from "./lib/ChameleonCardFooter.js";
3 | export { ChameleonCardFooterStyle } from "./lib/ChameleonCardFooterStyle.js";
4 | export { ChameleonCardHeader } from "./lib/ChameleonCardHeader.js";
5 | export { ChameleonCardHeaderStyle } from "./lib/ChameleonCardHeaderStyle.js";
6 | export { ChameleonCardImage } from "./lib/ChameleonCardImage.js";
7 | export { ChameleonCardImageStyle } from "./lib/ChameleonCardImageStyle.js";
8 | export { ChameleonCardStyle } from "./lib/ChameleonCardStyle.js";
9 |
--------------------------------------------------------------------------------
/packages/card/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@chameleon-ds/card",
3 | "version": "2.0.1",
4 | "description": "Chameleon card",
5 | "author": "Maritz Motivation Solutions, Inc.",
6 | "license": "MIT",
7 | "homepage": "https://github.com/MaritzSTL/chameleon/tree/master/packages/card#readme",
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/MaritzSTL/chameleon.git"
11 | },
12 | "main": "index.js",
13 | "module": "index.js",
14 | "files": [
15 | "chameleon-card.js",
16 | "chameleon-card-footer.js",
17 | "chameleon-card-header.js",
18 | "chameleon-card-image.js",
19 | "/lib/"
20 | ],
21 | "scripts": {
22 | "test": "echo \"Error: run tests from root\" && exit 1",
23 | "build": "babel src --out-dir lib --config-file ../../babel.config.json"
24 | },
25 | "bugs": {
26 | "url": "https://github.com/MaritzSTL/chameleon/issues"
27 | },
28 | "dependencies": {
29 | "lit-element": "^2.2.1"
30 | },
31 | "publishConfig": {
32 | "access": "public"
33 | },
34 | "gitHead": "903c637e2d1f3693b6c0b5fca5c1e6363ecb15c1"
35 | }
36 |
--------------------------------------------------------------------------------
/packages/card/src/ChameleonCard.js:
--------------------------------------------------------------------------------
1 | import { LitElement, html, property } from "lit-element";
2 | import { ChameleonCardStyle } from "./ChameleonCardStyle.js";
3 | import { nothing } from "lit-html";
4 |
5 | export class ChameleonCard extends LitElement {
6 | /**
7 | * Styles
8 | */
9 | static styles = [ChameleonCardStyle];
10 |
11 | /**
12 | * Properties
13 | */
14 | @property({ type: String })
15 | accentColor = null;
16 |
17 | @property({ type: String, reflect: true })
18 | complication = null;
19 |
20 | /**
21 | * Template
22 | */
23 | render() {
24 | return html`
25 | ${this.complicationText}
26 |
27 | `;
28 | }
29 |
30 | get complicationText() {
31 | return this.complication !== null
32 | ? html` ${this.complication}
`
33 | : nothing;
34 | }
35 |
36 | updated(changedProperties) {
37 | if (changedProperties.has("accentColor") && this.accentColor !== "")
38 | this.style.borderTop = `7px solid ${this.accentColor}`;
39 |
40 | if (
41 | changedProperties.has("accentColor") &&
42 | this.accentColor === "" &&
43 | this.accentColor !== undefined
44 | ) {
45 | this.style.borderTop = `7px solid var(--color-primary, #2c6fb7)`;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/packages/card/src/ChameleonCardFooter.js:
--------------------------------------------------------------------------------
1 | import { LitElement, html } from "lit-element";
2 | import { ChameleonCardFooterStyle } from "./ChameleonCardFooterStyle.js";
3 |
4 | export class ChameleonCardFooter extends LitElement {
5 | /**
6 | * Styles
7 | */
8 | static styles = [ChameleonCardFooterStyle];
9 |
10 | /**
11 | * Template
12 | */
13 | render() {
14 | return html` `;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/packages/card/src/ChameleonCardFooterStyle.js:
--------------------------------------------------------------------------------
1 | import { css } from "lit-element";
2 |
3 | export const ChameleonCardFooterStyle = css`
4 | :host {
5 | display: flex;
6 | margin: 1.5rem 0 0.625rem 0;
7 | }
8 | `;
9 |
--------------------------------------------------------------------------------
/packages/card/src/ChameleonCardHeader.js:
--------------------------------------------------------------------------------
1 | import { LitElement, html, property } from "lit-element";
2 | import { nothing } from "lit-html";
3 | import { ChameleonCardHeaderStyle } from "./ChameleonCardHeaderStyle.js";
4 |
5 | export class ChameleonCardHeader extends LitElement {
6 | /**
7 | * Styles
8 | */
9 | static styles = [ChameleonCardHeaderStyle];
10 |
11 | /**
12 | * Properties
13 | */
14 | @property({ type: String })
15 | title = "";
16 |
17 | @property({ type: String })
18 | subtitle = "";
19 |
20 | /**
21 | * Template
22 | */
23 | render() {
24 | return html`
25 | ${this.subtitle !== "" ? html`${this.subtitle} ` : nothing}
26 | ${this.title !== "" ? html`${this.title} ` : nothing}
27 | `;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/packages/card/src/ChameleonCardHeaderStyle.js:
--------------------------------------------------------------------------------
1 | import { css } from "lit-element";
2 | export const ChameleonCardHeaderStyle = css`
3 | :host {
4 | display: block;
5 | margin-bottom: 11px;
6 | }
7 |
8 | h3,
9 | h2 {
10 | overflow: hidden;
11 | margin: 0;
12 | text-overflow: ellipsis;
13 | }
14 |
15 | h3 {
16 | color: var(--color-secondary-dark, #349889);
17 | font-size: var(--font-size-subtitle, 0.938rem);
18 | line-height: 21px;
19 | white-space: nowrap;
20 | }
21 |
22 | h2 {
23 | font-size: var(--font-size-title, 1.4rem);
24 | line-height: 27px;
25 | max-height: 52px;
26 | }
27 | `;
28 |
--------------------------------------------------------------------------------
/packages/card/src/ChameleonCardImage.js:
--------------------------------------------------------------------------------
1 | import { LitElement, html, property } from "lit-element";
2 | import { ChameleonCardImageStyle } from "./ChameleonCardImageStyle.js";
3 |
4 | export class ChameleonCardImage extends LitElement {
5 | /**
6 | * Properties
7 | */
8 |
9 | // The image's source URL
10 | @property({ type: String })
11 | src = "";
12 |
13 | // The image's alt text
14 | @property({ type: String })
15 | alt = "";
16 |
17 | /**
18 | * Styles
19 | */
20 | static styles = [ChameleonCardImageStyle];
21 |
22 | /**
23 | * Template
24 | */
25 | render() {
26 | return this.src !== ""
27 | ? html` `
28 | : html`
`;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/packages/card/src/ChameleonCardImageStyle.js:
--------------------------------------------------------------------------------
1 | import { css } from "lit-element";
2 |
3 | export const ChameleonCardImageStyle = css`
4 | :host {
5 | display: inline-block;
6 | }
7 |
8 | img {
9 | border-radius: var(--border-radius, 0.5rem);
10 | vertical-align: top;
11 | width: 100%;
12 | }
13 |
14 | .placeholder {
15 | background-image: linear-gradient(
16 | to top,
17 | var(--color-primary-dark, #004587),
18 | var(--color-primary-light, #679dea)
19 | );
20 | border-radius: var(--border-radius, 0.5rem);
21 | min-height: 100px;
22 | }
23 | `;
24 |
--------------------------------------------------------------------------------
/packages/card/src/ChameleonCardStyle.js:
--------------------------------------------------------------------------------
1 | import { css } from "lit-element";
2 |
3 | export const ChameleonCardStyle = css`
4 | :host {
5 | background-color: var(--color-surface, #ffffff);
6 | display: flex;
7 | flex-direction: column;
8 | justify-content: space-between;
9 | padding: 16px;
10 | }
11 |
12 | :host([outline]) {
13 | border: 1px solid var(--color-gray-lightest, #e1e3e4);
14 | }
15 |
16 | :host([rounded]) {
17 | border-radius: var(--border-radius, 0.5rem);
18 | }
19 |
20 | :host([complication]) {
21 | padding-top: 35px;
22 | position: relative;
23 | }
24 |
25 | .complication {
26 | background-color: var(--color-secondary, #69c9b9);
27 | border-radius: var(--border-radius, 0.5rem) 0 var(--border-radius, 0.5rem) 0;
28 | font-size: var(--font-size-label, 0.875rem);
29 | padding: 4px 16px;
30 | color: var(--color-surface, #ffffff);
31 | position: absolute;
32 | top: 0;
33 | left: 0;
34 | }
35 | `;
36 |
--------------------------------------------------------------------------------
/packages/chart/README.md:
--------------------------------------------------------------------------------
1 | # Chameleon Chart
2 |
3 | ```js script
4 | import { html } from "@open-wc/demoing-storybook";
5 | import { withKnobs, text, number } from "@open-wc/demoing-storybook";
6 | import "./chameleon-chart.js";
7 |
8 | export default {
9 | title: "Components|Data and Visualizations/Chart",
10 | component: "chameleon-chart",
11 | decorators: [withKnobs],
12 | options: { selectedPanel: "storybookjs/docs/panel" },
13 | };
14 | ```
15 |
16 | ## Properties
17 |
18 | | Property Name | Type(s) | Default Value | Description |
19 | | ------------- | ------- | ------------- | ------------------------------------------- |
20 | | `type` | String | `""` | The type of chart |
21 | | `color` | String | `"#00870a"` | The hex value of the chart color |
22 | | `percentage` | Number | `0` | The percentage to be displayed in the chart |
23 | | `label` | String | `"0"` | The value to show in the label |
24 | | `subLabel` | String | `""` | The value to show in the sublabel |
25 |
26 | ## Examples
27 |
28 | ### Default
29 |
30 | ```js preview-story
31 | export const Default = () => {
32 | const color = text("Color", "#00870a");
33 | const label = text("Label", "1,000");
34 | const subLabel = text("SubLabel", "Funds Remaining");
35 | const percentage = number("Percentage", 90);
36 |
37 | return html`
38 |
45 | `;
46 | };
47 | ```
48 |
--------------------------------------------------------------------------------
/packages/chart/__tests__/chameleon-chart.test.js:
--------------------------------------------------------------------------------
1 | import "../chameleon-chart.js";
2 | import { litFixture, html, expect } from "@open-wc/testing";
3 |
4 | const fixture = html` `;
5 |
6 | describe("chameleon-chart", () => {
7 | let element;
8 |
9 | beforeEach(async () => {
10 | element = await litFixture(fixture);
11 | });
12 |
13 | it("renders", async () => {
14 | expect(Boolean(element.shadowRoot)).to.equal(true);
15 | });
16 |
17 | it("convert percentage to degrees", async () => {
18 | const percentage = 10;
19 |
20 | const degrees = element._percentageToDegrees(percentage);
21 | const expectedDegrees = -96;
22 | expect(degrees).to.be.equal(expectedDegrees);
23 | });
24 |
25 | it("returns the arc chart type", async () => {
26 | element.type = "arc";
27 | const chart = await litFixture(element.chart);
28 |
29 | expect(chart).lightDom.to.equalSnapshot();
30 | });
31 | });
32 |
--------------------------------------------------------------------------------
/packages/chart/chameleon-chart.js:
--------------------------------------------------------------------------------
1 | import { ChameleonChart } from "./lib/ChameleonChart.js";
2 |
3 | customElements.define("chameleon-chart", ChameleonChart);
4 |
--------------------------------------------------------------------------------
/packages/chart/index.js:
--------------------------------------------------------------------------------
1 | export { ChameleonChart } from "./lib/ChameleonChart.js";
2 | export { ChameleonChartStyle } from "./lib/ChameleonChartStyle.js";
3 |
--------------------------------------------------------------------------------
/packages/chart/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@chameleon-ds/chart",
3 | "version": "2.0.1",
4 | "description": "Chameleon chart",
5 | "author": "Maritz Motivation Solutions, Inc.",
6 | "license": "MIT",
7 | "homepage": "https://github.com/MaritzSTL/chameleon/tree/master/packages/chart#readme",
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/MaritzSTL/chameleon.git"
11 | },
12 | "main": "index.js",
13 | "module": "index.js",
14 | "files": [
15 | "chameleon-chart.js",
16 | "/lib/"
17 | ],
18 | "scripts": {
19 | "test": "echo \"Error: run tests from root\" && exit 1",
20 | "build": "babel src --out-dir lib --config-file ../../babel.config.json"
21 | },
22 | "bugs": {
23 | "url": "https://github.com/MaritzSTL/chameleon/issues"
24 | },
25 | "dependencies": {
26 | "lit-element": "^2.2.1"
27 | },
28 | "publishConfig": {
29 | "access": "public"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/packages/chart/src/ChameleonChart.js:
--------------------------------------------------------------------------------
1 | import { LitElement, property, html, svg } from "lit-element";
2 | import { ChameleonChartStyle } from "./ChameleonChartStyle.js";
3 | import { nothing } from "lit-html";
4 |
5 | export class ChameleonChart extends LitElement {
6 | /**
7 | * Properties
8 | */
9 | @property({ type: String })
10 | type = "";
11 |
12 | /*The color of the chart*/
13 |
14 | @property({ type: String, reflect: true })
15 | color = "#00870a";
16 |
17 | /* percentage to be displayed in the donut chart */
18 | @property({ type: Number })
19 | percentage = 0;
20 |
21 | /* value to show in the the label */
22 | @property({ type: String })
23 | label = "0";
24 |
25 | /* value to show in the the subLabel */
26 | @property({ type: String })
27 | subLabel = "";
28 |
29 | /**
30 | * Styles
31 | */
32 | static styles = [ChameleonChartStyle];
33 |
34 | /**
35 | * Template
36 | */
37 | render() {
38 | return html`
39 | ${this.chart}
40 |
41 | ${this.label}
42 | ${this.subLabel}
43 |
44 | `;
45 | }
46 |
47 | get chart() {
48 | switch (this.type) {
49 | case "arc":
50 | return this.arc;
51 | default:
52 | return nothing;
53 | }
54 | }
55 |
56 | get arc() {
57 | return svg`
58 |
59 |
66 |
75 |
76 | `;
77 | }
78 |
79 | _polarToCartesian(centerX, centerY, radius, angleInDegrees) {
80 | const angleInRadians = ((angleInDegrees - 90) * Math.PI) / 180.0;
81 |
82 | return {
83 | x: centerX + radius * Math.cos(angleInRadians),
84 | y: centerY + radius * Math.sin(angleInRadians),
85 | };
86 | }
87 |
88 | _percentageToDegrees(percentage) {
89 | const degrees = (percentage / 100) * 240 - 120;
90 |
91 | return degrees;
92 | }
93 |
94 | _describeArc(x, y, radius, startAngle, endAngle) {
95 | const start = this._polarToCartesian(x, y, radius, endAngle);
96 | const end = this._polarToCartesian(x, y, radius, startAngle);
97 |
98 | const largeArcFlag = endAngle - startAngle <= 180 ? "0" : "1";
99 |
100 | const d = [
101 | "M",
102 | start.x,
103 | start.y,
104 | "A",
105 | radius,
106 | radius,
107 | 0,
108 | largeArcFlag,
109 | 0,
110 | end.x,
111 | end.y,
112 | ].join(" ");
113 |
114 | return d;
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/packages/chart/src/ChameleonChartStyle.js:
--------------------------------------------------------------------------------
1 | import { css } from "lit-element";
2 |
3 | export const ChameleonChartStyle = css`
4 | :host {
5 | display: inline-block;
6 | max-width: 130px;
7 | }
8 |
9 | .labels {
10 | text-align: center;
11 | }
12 |
13 | label {
14 | display: block;
15 | color: var(--color-gray-dark, #9fa4a8);
16 | font-size: 0.75rem;
17 | }
18 | `;
19 |
--------------------------------------------------------------------------------
/packages/checkbox/README.md:
--------------------------------------------------------------------------------
1 | # Chameleon Checkbox
2 |
3 | ```js script
4 | import { html } from "@open-wc/demoing-storybook";
5 | import { withKnobs, text, boolean } from "@open-wc/demoing-storybook";
6 | import "./chameleon-checkbox.js";
7 |
8 | export default {
9 | title: "Components|Form Elements/Checkbox",
10 | component: "chameleon-checkbox",
11 | decorators: [withKnobs],
12 | options: { selectedPanel: "storybookjs/docs/panel" },
13 | };
14 | ```
15 |
16 | ## Properties
17 |
18 | | Property Name | Type(s) | Default Value | Description |
19 | | ------------- | ------- | ---------------- | -------------------------------------------------------------------------------- |
20 | | `label` | String | `""` | The checkbox's label |
21 | | `name` | String | `"cha-checkbox"` | The checkbox's form name |
22 | | `checked` | Boolean | `false` | A Boolean which, if true, indicates that the checkbox is selected |
23 | | `value` | String | `""` | The checkbox's current value |
24 | | `readonly` | Boolean | `false` | A Boolean attribute which, if true, indicates that the checkbox cannot be edited |
25 | | `disabled` | Boolean | `false` | The checkbox's enabled/disabled status |
26 | | `invalid` | Boolean | `false` | Invalid boolean to allow validity access from higher level form errors |
27 | | `required` | boolean | `false` | A Boolean to indicate the input is required |
28 |
29 | ## Examples
30 |
31 | ### Default
32 |
33 | ```js preview-story
34 | export const Default = () => {
35 | const label = text("Label", "");
36 | const checked = boolean("Checked", true);
37 | const disabled = boolean("Disabled", false);
38 | const invalid = boolean("Invalid", false);
39 |
40 | return html`
41 |
47 | `;
48 | };
49 | ```
50 |
--------------------------------------------------------------------------------
/packages/checkbox/__tests__/chameleon-checkbox.test.js:
--------------------------------------------------------------------------------
1 | import { litFixture, html, expect } from "@open-wc/testing";
2 | import "../chameleon-checkbox.js";
3 |
4 | const fixture = html` `;
5 |
6 | describe("chameleon-checkbox", () => {
7 | let element;
8 |
9 | beforeEach(async () => {
10 | element = await litFixture(fixture);
11 | });
12 |
13 | it("renders", () => {
14 | expect(Boolean(element.shadowRoot)).to.equal(true);
15 | });
16 |
17 | it("shows label text", () => {
18 | element.label = "chameleon";
19 | expect(element.labelText).to.equal("chameleon");
20 | });
21 | it("shows aria-invalid when invalid", () => {
22 | element.invalid = true;
23 | expect(element).shadowDom.to.equalSnapshot();
24 | });
25 | it("shows name attribute", () => {
26 | element.name = "formName";
27 | expect(element).shadowDom.to.equalSnapshot();
28 | });
29 | it("shows required attribute", async () => {
30 | element.required = true;
31 | await element.updateComplete;
32 | expect(element).shadowDom.to.equalSnapshot();
33 | });
34 | it("shows readonly attribute", () => {
35 | element.readonly = true;
36 | expect(element).shadowDom.to.equalSnapshot();
37 | });
38 | });
39 |
--------------------------------------------------------------------------------
/packages/checkbox/chameleon-checkbox.js:
--------------------------------------------------------------------------------
1 | import { ChameleonCheckbox } from "./lib/ChameleonCheckbox.js";
2 |
3 | customElements.define("chameleon-checkbox", ChameleonCheckbox);
4 |
--------------------------------------------------------------------------------
/packages/checkbox/index.js:
--------------------------------------------------------------------------------
1 | export { ChameleonCheckbox } from "./lib/ChameleonCheckbox.js";
2 | export { ChameleonCheckboxStyle } from "./lib/ChameleonCheckboxStyle.js";
3 |
--------------------------------------------------------------------------------
/packages/checkbox/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@chameleon-ds/checkbox",
3 | "version": "2.0.1",
4 | "description": "Chameleon checkbox",
5 | "author": "Maritz Motivation Solutions, Inc.",
6 | "license": "MIT",
7 | "homepage": "https://github.com/MaritzSTL/chameleon/tree/master/packages/checkbox#readme",
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/MaritzSTL/chameleon.git"
11 | },
12 | "main": "index.js",
13 | "module": "index.js",
14 | "files": [
15 | "chameleon-checkbox.js",
16 | "/lib/"
17 | ],
18 | "scripts": {
19 | "test": "echo \"Error: run tests from root\" && exit 1",
20 | "build": "babel src --out-dir lib --config-file ../../babel.config.json"
21 | },
22 | "bugs": {
23 | "url": "https://github.com/MaritzSTL/chameleon/issues"
24 | },
25 | "dependencies": {
26 | "lit-element": "^2.2.1"
27 | },
28 | "publishConfig": {
29 | "access": "public"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/packages/checkbox/src/ChameleonCheckbox.js:
--------------------------------------------------------------------------------
1 | import { LitElement, html, property } from "lit-element";
2 | import { nothing } from "lit-html";
3 | import { ChameleonCheckboxStyle } from "./ChameleonCheckboxStyle.js";
4 |
5 | export class ChameleonCheckbox extends LitElement {
6 | /**
7 | * Properties
8 | */
9 |
10 | // The checkbox's label
11 | @property({ type: String })
12 | label = "";
13 |
14 | // The checkbox's form name
15 | @property({ type: String })
16 | name = "cha-checkbox";
17 |
18 | // A Boolean which, if true, indicates that the checkbox is selected
19 | @property({ type: Boolean, reflect: true })
20 | checked = false;
21 |
22 | // The checkbox's current value
23 | @property({ type: String })
24 | value = "";
25 |
26 | // A Boolean attribute which, if true, indicates that the checkbox cannot be edited
27 | @property({ type: Boolean, reflect: true })
28 | readonly = false;
29 |
30 | // The checkbox's enabled/disabled status
31 | @property({ type: Boolean, reflect: true })
32 | disabled = false;
33 |
34 | // Invalid boolean to allow validity access from higher level form errors
35 | @property({ type: Boolean, reflect: true })
36 | invalid = false;
37 |
38 | // A Boolean to indicate the input is required
39 | @property({ type: Boolean, reflect: true })
40 | required = false;
41 |
42 | /**
43 | * Styles
44 | */
45 | static styles = [ChameleonCheckboxStyle];
46 |
47 | /**
48 | * Template
49 | */
50 | render() {
51 | return html`
52 |
63 |
64 | ${this.labelText}
65 | `;
66 | }
67 |
68 | get labelText() {
69 | if (this.label !== "") return this.label;
70 | else return nothing;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/packages/checkbox/src/ChameleonCheckboxStyle.js:
--------------------------------------------------------------------------------
1 | import { css } from "lit-element";
2 |
3 | export const ChameleonCheckboxStyle = css`
4 | :host([readonly]),
5 | :host([disabled]) {
6 | pointer-events: none;
7 | }
8 |
9 | :host {
10 | align-items: center;
11 | cursor: pointer;
12 | display: inline-flex;
13 | font-size: var(--font-size-input, 0.938rem);
14 | -webkit-user-select: none;
15 | -moz-user-select: none;
16 | -ms-user-select: none;
17 | user-select: none;
18 | vertical-align: top;
19 | }
20 |
21 | input {
22 | cursor: pointer;
23 | display: none;
24 | }
25 |
26 | .checkmark {
27 | background-color: transparent;
28 | border: 2px solid var(--color-gray-lightest, #e1e3e4);
29 | border-radius: 3px;
30 | box-sizing: border-box;
31 | display: inline-block;
32 | height: 20px;
33 | margin-right: 10px;
34 | position: relative;
35 | width: 20px;
36 | }
37 |
38 | :host:hover input ~ .checkmark {
39 | background-color: var(--color-surface, #ffffff);
40 | }
41 |
42 | input:checked ~ .checkmark {
43 | background-color: var(--color-primary, #2c6fb7);
44 | border: none;
45 | }
46 |
47 | .checkmark:after {
48 | border-bottom: 2px solid var(--color-surface, #ffffff);
49 | border-right: 2px solid var(--color-surface, #ffffff);
50 | content: "";
51 | display: none;
52 | height: 13px;
53 | margin-left: 7px;
54 | margin-top: 1px;
55 | transform: rotate(45deg);
56 | width: 4px;
57 | }
58 |
59 | input:checked ~ .checkmark::after {
60 | display: inline-block;
61 | }
62 |
63 | :host([invalid]) .checkmark {
64 | border-color: var(--color-error, #bc1c16);
65 | }
66 |
67 | :host([invalid]) input:checked ~ .checkmark {
68 | border: 2px solid var(--color-error, #bc1c16);
69 | }
70 |
71 | :host([invalid]) input:checked ~ .checkmark:after {
72 | margin-top: -1px;
73 | margin-left: 5px;
74 | }
75 |
76 | :host([disabled]) {
77 | pointer-events: none;
78 | }
79 |
80 | :host([disabled]) input:checked ~ .checkmark {
81 | background-color: var(--color-gray-lightest, #e1e3e4);
82 | }
83 |
84 | :host([disabled]) .checkmark {
85 | position: relative;
86 | }
87 |
88 | :host([disabled]) .checkmark:after {
89 | border: none;
90 | background-color: var(--color-surface, #ffffff);
91 | height: 2px;
92 | left: 50%;
93 | margin: 0;
94 | position: absolute;
95 | top: 50%;
96 | transform: translate(-50%, -50%);
97 | width: 12px;
98 | }
99 | `;
100 |
--------------------------------------------------------------------------------
/packages/chip/README.md:
--------------------------------------------------------------------------------
1 | # Chameleon Chip
2 |
3 | ```js script
4 | import { html } from "@open-wc/demoing-storybook";
5 | import "./chameleon-chip.js";
6 |
7 | export default {
8 | title: "Components|Data and Visualizations/Chip",
9 | component: "chameleon-chip",
10 | options: { selectedPanel: "storybookjs/docs/panel" },
11 | };
12 | ```
13 |
14 | ## Properties
15 |
16 | | Property Name | Type(s) | Default Value | Description |
17 | | ------------- | ------- | ------------- | ------------------------------------- |
18 | | `closeable` | Boolean | `false` | Whether or not the chip can be closed |
19 | | `value` | String | `""` | The chip's value |
20 |
21 | ## Examples
22 |
23 | ### Default
24 |
25 | ```js preview-story
26 | export const Default = () => html` Filter `;
27 | ```
28 |
29 | ### Closeable
30 |
31 | ```js preview-story
32 | export const Closeable = () => html`
33 | Filter
34 | `;
35 | ```
36 |
--------------------------------------------------------------------------------
/packages/chip/__tests__/chameleon-chip.test.js:
--------------------------------------------------------------------------------
1 | import { litFixture, html, expect } from "@open-wc/testing";
2 | import sinon from "sinon";
3 | import "../chameleon-chip.js";
4 |
5 | const fixture = html` chameleon `;
6 |
7 | describe("chameleon-chip", () => {
8 | let element;
9 |
10 | beforeEach(async () => {
11 | element = await litFixture(fixture);
12 | });
13 |
14 | it("renders", async () => {
15 | expect(Boolean(element.shadowRoot)).to.equal(true);
16 | });
17 |
18 | it("_remove dispatches an event with the value", () => {
19 | const dispatchEvent = sinon.spy(element, "dispatchEvent");
20 |
21 | element._remove();
22 |
23 | expect(dispatchEvent).to.be.calledOnce;
24 | });
25 |
26 | // Would like to rewrite this to be better
27 | it("renders the removeIcon", async () => {
28 | const icon = await litFixture(element.removeIcon);
29 |
30 | expect(icon).to.contain.html(" {
34 | element.value = "chameleon";
35 | element.requestUpdate();
36 | await element.updateComplete;
37 |
38 | expect(element.value).to.equal("chameleon");
39 | });
40 |
41 | it("renders close icon if [closeable] is true", async () => {
42 | element.closeable = true;
43 | element.requestUpdate();
44 | await element.updateComplete;
45 |
46 | expect(element).shadowDom.to.equal(` `);
47 | });
48 | });
49 |
--------------------------------------------------------------------------------
/packages/chip/chameleon-chip.js:
--------------------------------------------------------------------------------
1 | import { ChameleonChip } from "./lib/ChameleonChip.js";
2 |
3 | customElements.define("chameleon-chip", ChameleonChip);
4 |
--------------------------------------------------------------------------------
/packages/chip/index.js:
--------------------------------------------------------------------------------
1 | export { ChameleonChip } from "./lib/ChameleonChip.js";
2 | export { ChameleonChipStyle } from "./lib/ChameleonChipStyle.js";
3 |
--------------------------------------------------------------------------------
/packages/chip/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@chameleon-ds/chip",
3 | "version": "2.0.1",
4 | "description": "Chameleon chip",
5 | "author": "Maritz Motivation Solutions, Inc.",
6 | "license": "MIT",
7 | "homepage": "https://github.com/MaritzSTL/chameleon/tree/master/packages/chip#readme",
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/MaritzSTL/chameleon.git"
11 | },
12 | "main": "index.js",
13 | "module": "index.js",
14 | "files": [
15 | "chameleon-chip.js",
16 | "/lib/"
17 | ],
18 | "scripts": {
19 | "test": "echo \"Error: run tests from root\" && exit 1",
20 | "build": "babel src --out-dir lib --config-file ../../babel.config.json"
21 | },
22 | "bugs": {
23 | "url": "https://github.com/MaritzSTL/chameleon/issues"
24 | },
25 | "dependencies": {
26 | "lit-element": "^2.2.1"
27 | },
28 | "publishConfig": {
29 | "access": "public"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/packages/chip/src/ChameleonChip.js:
--------------------------------------------------------------------------------
1 | import { LitElement, property, html, svg } from "lit-element";
2 | import { nothing } from "lit-html";
3 | import { ChameleonChipStyle } from "./ChameleonChipStyle.js";
4 |
5 | export class ChameleonChip extends LitElement {
6 | /**
7 | * Properties
8 | */
9 | @property({ type: Boolean, reflect: true })
10 | closeable = false;
11 |
12 | @property({ type: String })
13 | _value = "";
14 |
15 | /**
16 | * Styles
17 | */
18 | static styles = [ChameleonChipStyle];
19 |
20 | /**
21 | * Template
22 | */
23 | render() {
24 | return html`
25 |
26 | ${this.closeable
27 | ? html` ${this.removeIcon} `
28 | : nothing}
29 | `;
30 | }
31 |
32 | _remove() {
33 | const e = new CustomEvent("remove-chip", {
34 | detail: { value: this.value },
35 | bubbles: true,
36 | composed: true,
37 | });
38 |
39 | this.dispatchEvent(e);
40 | }
41 |
42 | get removeIcon() {
43 | return svg` `;
44 | }
45 |
46 | get value() {
47 | if (this._value !== "") {
48 | return this._value;
49 | } else {
50 | return this.innerText;
51 | }
52 | }
53 |
54 | set value(value) {
55 | this._value = value;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/packages/chip/src/ChameleonChipStyle.js:
--------------------------------------------------------------------------------
1 | import { css } from "lit-element";
2 |
3 | export const ChameleonChipStyle = css`
4 | :host {
5 | align-items: center;
6 | background-color: var(--color-primary, #2c6fb7);
7 | border-radius: 1.25rem;
8 | color: var(--color-surface, #ffffff);
9 | display: inline-flex;
10 | flex-direction: row;
11 | font-size: var(--font-size-input, 0.938rem);
12 | line-height: 1.125rem;
13 | padding: 4px 11px;
14 | transition: background-color 0.3s ease;
15 | }
16 |
17 | :host([closeable]:hover) {
18 | background-color: var(--color-primary-dark, #004587);
19 | }
20 |
21 | span {
22 | display: flex;
23 | cursor: pointer;
24 | }
25 |
26 | svg {
27 | padding-left: 10px;
28 | height: 13px;
29 | }
30 | `;
31 |
--------------------------------------------------------------------------------
/packages/date/README.md:
--------------------------------------------------------------------------------
1 | # Chameleon Date
2 |
3 | ```js script
4 | import { html } from "@open-wc/demoing-storybook";
5 | import { withKnobs, text, boolean } from "@open-wc/demoing-storybook";
6 | import "./chameleon-date.js";
7 |
8 | export default {
9 | title: "Components|Form Elements/Date",
10 | component: "chameleon-date",
11 | decorators: [withKnobs],
12 | options: { selectedPanel: "storybookjs/docs/panel" },
13 | };
14 | ```
15 |
16 | ## Properties
17 |
18 | | Property Name | Type(s) | Default Value | Description |
19 | | ------------------- | ------- | ------------- | ------------------------------------------------ |
20 | | `name` | String | `"cha-date"` | The date's form name |
21 | | `active` | Boolean | `false` | Whether or not the date picker drawer is open |
22 | | `renderedDate` | Object | `null` | The Date object of the rendered date |
23 | | `placeholder` | String | `""` | The date's placeholder text |
24 | | `label` | String | `""` | The date's label text |
25 | | `readonly` | Boolean | `false` | Whether or not the date picker is readonly |
26 | | `value` | String | `""` | The date picker's text value (YYYY-MM-DD) |
27 | | `min` | String | `null` | The date picker's minimum value (YYYY-MM-DD) |
28 | | `max` | String | `null` | The date picker's maximum value (YYYY-MM-DD) |
29 | | `required` | Boolean | `false` | Whether or not the date value is required |
30 | | `canDelete` | Boolean | `true` | If the date is able to be deleted |
31 | | `disabled` | Boolean | `false` | Whether or not the date picker is disabled |
32 | | `validationMessage` | String | `""` | The date picker's validation message |
33 | | `invalid` | Boolean | `false` | Whether or not the date picker is invalid |
34 | | `overlayRenderMode` | String | `"month"` | The date picker's overlay mode ("year", "month") |
35 |
36 | ## Examples
37 |
38 | ### Default
39 |
40 | ```js preview-story
41 | export const Default = () => {
42 | const placeholder = text("Placeholder", "Select Date");
43 | const label = text("Label", "Date *");
44 | const minValue = text("Min Value (YYYY-MM-DD)", "");
45 | const maxValue = text("Max Value (YYYY-MM-DD)", "");
46 | const readonly = boolean("Read Only", false);
47 | const invalid = boolean("Invalid", false);
48 | const required = boolean("Required", false);
49 | const disabled = boolean("Disabled", false);
50 | const error = text("Error", "");
51 | const name = text("Name", "input-form-name");
52 |
53 | return html`
54 |
66 | `;
67 | };
68 | ```
69 |
70 | ### Error State
71 |
72 | ```js preview-story
73 | export const ErrorState = () => html`
74 |
80 | `;
81 | ```
82 |
--------------------------------------------------------------------------------
/packages/date/chameleon-date.js:
--------------------------------------------------------------------------------
1 | import { ChameleonDate } from "./lib/ChameleonDate.js";
2 |
3 | customElements.define("chameleon-date", ChameleonDate);
4 |
--------------------------------------------------------------------------------
/packages/date/index.js:
--------------------------------------------------------------------------------
1 | export { ChameleonDate } from "./lib/ChameleonDate.js";
2 | export { ChameleonDateStyle } from "./lib/ChameleonDateStyle.js";
3 |
--------------------------------------------------------------------------------
/packages/date/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@chameleon-ds/date",
3 | "version": "2.0.1",
4 | "description": "Chameleon date",
5 | "author": "Maritz Motivation Solutions, Inc.",
6 | "license": "MIT",
7 | "homepage": "https://github.com/MaritzSTL/chameleon/tree/master/packages/date#readme",
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/MaritzSTL/chameleon.git"
11 | },
12 | "main": "index.js",
13 | "module": "index.js",
14 | "files": [
15 | "chameleon-date.js",
16 | "/lib/"
17 | ],
18 | "scripts": {
19 | "test": "echo \"Error: run tests from root\" && exit 1",
20 | "build": "babel src --out-dir lib --config-file ../../babel.config.json"
21 | },
22 | "bugs": {
23 | "url": "https://github.com/MaritzSTL/chameleon/issues"
24 | },
25 | "dependencies": {
26 | "@chameleon-ds/button": "^2.0.1",
27 | "@chameleon-ds/input": "^2.0.1",
28 | "lit-element": "^2.2.1"
29 | },
30 | "publishConfig": {
31 | "access": "public"
32 | },
33 | "gitHead": "f42fb52b4423dce1ed5f2d20344fc254da1daf36"
34 | }
35 |
--------------------------------------------------------------------------------
/packages/dialog/README.md:
--------------------------------------------------------------------------------
1 | # Chameleon Dialog
2 |
3 | ```js script
4 | import { html, svg } from "lit-html";
5 | import { withKnobs, text, boolean } from "@open-wc/demoing-storybook";
6 | import "./chameleon-dialog.js";
7 |
8 | export default {
9 | title: "Components|Overlays/Dialog",
10 | component: "chameleon-dialog",
11 | decorators: [withKnobs],
12 | options: { selectedPanel: "storybookjs/docs/panel" },
13 | };
14 | ```
15 |
16 | ## Properties
17 |
18 | | Property Name | Type(s) | Default Value | Description |
19 | | ------------- | ------- | ------------- | ---------------------------------------- |
20 | | `open` | Boolean | `false` | Whether or not the dialog is open |
21 | | `icon` | Boolean | `false` | Whether or not the card has an icon |
22 | | `dismissible` | Boolean | `false` | Whether or not the card has a close icon |
23 | | `canGoBack` | Boolean | `false` | Whether or not the dialog can go back |
24 | | `fullScreen` | Boolean | `false` | Display full screen |
25 |
26 | ## Examples
27 |
28 | ### Default
29 |
30 | ```js preview-story
31 | export const Default = () => {
32 | const defaultIcon = svg`
33 |
34 | `;
35 |
36 | return html`
37 |
38 | ${defaultIcon}
39 | Title
40 | We’re sorry but your session has expired. You will need to log back in to
41 | continue.
42 |
43 |
44 | Okay
45 |
46 |
47 |
48 |
49 | Cancel
50 |
51 |
52 |
53 | `;
54 | };
55 | ```
56 |
--------------------------------------------------------------------------------
/packages/dialog/chameleon-dialog.js:
--------------------------------------------------------------------------------
1 | import { ChameleonDialog } from "./lib/ChameleonDialog.js";
2 |
3 | customElements.define("chameleon-dialog", ChameleonDialog);
4 |
--------------------------------------------------------------------------------
/packages/dialog/index.js:
--------------------------------------------------------------------------------
1 | export { ChameleonDialog } from "./lib/ChameleonDialog.js";
2 | export { ChameleonDialogStyle } from "./lib/ChameleonDialogStyle.js";
3 |
--------------------------------------------------------------------------------
/packages/dialog/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@chameleon-ds/dialog",
3 | "version": "2.1.0",
4 | "description": "Chameleon dialog",
5 | "author": "Maritz Motivation Solutions, Inc.",
6 | "license": "MIT",
7 | "homepage": "https://github.com/MaritzSTL/chameleon/tree/master/packages/dialog#readme",
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/MaritzSTL/chameleon.git"
11 | },
12 | "main": "index.js",
13 | "module": "index.js",
14 | "files": [
15 | "chameleon-dialog.js",
16 | "/lib/"
17 | ],
18 | "scripts": {
19 | "test": "echo \"Error: run tests from root\" && exit 1",
20 | "build": "babel src --out-dir lib --config-file ../../babel.config.json"
21 | },
22 | "bugs": {
23 | "url": "https://github.com/MaritzSTL/chameleon/issues"
24 | },
25 | "dependencies": {
26 | "@chameleon-ds/button": "^2.0.1",
27 | "@chameleon-ds/card": "^2.0.1",
28 | "lit-element": "^2.2.1"
29 | },
30 | "publishConfig": {
31 | "access": "public"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/packages/dialog/src/ChameleonDialogStyle.js:
--------------------------------------------------------------------------------
1 | import { css } from "lit-element";
2 |
3 | export const ChameleonDialogStyle = css`
4 | .open {
5 | display: flex;
6 | }
7 | .close {
8 | display: none;
9 | }
10 | .dialog {
11 | display: flex;
12 | flex-direction: column;
13 | align-items: center;
14 | align-content: center;
15 | padding: 0.5em;
16 | }
17 |
18 | .overlay {
19 | width: 100vw;
20 | height: 100vh;
21 | background-color: rgba(0, 0, 0, 0.4);
22 | position: fixed;
23 | top: 0;
24 | right: 0;
25 | bottom: 0;
26 | left: 0;
27 | z-index: 9999;
28 | }
29 |
30 | chameleon-card {
31 | flex-direction: column;
32 | border-top: solid var(--color-secondary) 10px;
33 | position: absolute;
34 | left: 50%;
35 | top: 50%;
36 | transform: translate(-50%, -50%);
37 | border-radius: 5px;
38 | box-shadow: 0 5px 12px 0 rgba(44, 111, 183, 0.2),
39 | 0 2px 6px -1px rgba(44, 111, 183, 0.12),
40 | 0 1px 4px 0 rgba(44, 111, 183, 0.14);
41 | margin: auto;
42 | background-color: #ffffff;
43 | width: var(--dialog-width, 18.75rem);
44 | padding: 48px;
45 | animation-name: dialogopen;
46 | animation-duration: 1s;
47 | }
48 |
49 | .full-screen {
50 | border-radius: unset;
51 | position: relative;
52 | width: 100%;
53 | margin-bottom: 0;
54 | margin-top: 0;
55 | }
56 |
57 | .actions {
58 | display: flex;
59 | flex-direction: column;
60 | align-self: stretch;
61 | margin-top: 1.5em;
62 | }
63 |
64 | .close-icon {
65 | display: flex;
66 | cursor: pointer;
67 | position: absolute;
68 | margin: 0;
69 | top: 25px;
70 | right: 25px;
71 | }
72 |
73 | .back-icon {
74 | display: flex;
75 | cursor: pointer;
76 | position: absolute;
77 | margin: 0;
78 | top: 25px;
79 | left: 25px;
80 | }
81 |
82 | svg {
83 | width: 100%;
84 | height: 100%;
85 | color: var(--color-gray-darkest);
86 | }
87 |
88 | :slotted(*) {
89 | color: var(--color-gray-darkest);
90 | height: 1.125em;
91 | position: absolute;
92 | top: 50%;
93 | transform: translateY(-50%);
94 | width: auto;
95 | }
96 |
97 | ::slotted([slot="icon"]) {
98 | color: var(--color-secondary-dark, #349889);
99 | height: 2.625em;
100 | }
101 |
102 | ::slotted([slot="title"]) {
103 | color: var(--color-primary);
104 | font-size: 2em;
105 | font-weight: 300;
106 | letter-spacing: 0.016em;
107 | margin: 1em 0;
108 | }
109 |
110 | ::slotted([slot="accept-action"]) {
111 | margin-top: 1em;
112 | }
113 |
114 | ::slotted([slot="decline-action"]) {
115 | margin-top: 1em;
116 | }
117 |
118 | @keyframes dialogopen {
119 | from {
120 | opacity: 0;
121 | }
122 | to {
123 | opacity: 1;
124 | }
125 | }
126 | `;
127 |
--------------------------------------------------------------------------------
/packages/hero/chameleon-hero.js:
--------------------------------------------------------------------------------
1 | import { ChameleonHero } from "./lib/ChameleonHero.js";
2 |
3 | customElements.define("chameleon-hero", ChameleonHero);
4 |
--------------------------------------------------------------------------------
/packages/hero/index.js:
--------------------------------------------------------------------------------
1 | export { ChameleonHero } from "./lib/ChameleonHero.js";
2 | export { ChameleonHeroStyle } from "./lib/ChameleonHeroStyle.js";
3 |
--------------------------------------------------------------------------------
/packages/hero/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@chameleon-ds/hero",
3 | "version": "2.0.1",
4 | "description": "Chameleon hero",
5 | "author": "Maritz Motivation Solutions, Inc.",
6 | "license": "MIT",
7 | "homepage": "https://github.com/MaritzSTL/chameleon/tree/master/packages/hero#readme",
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/MaritzSTL/chameleon.git"
11 | },
12 | "main": "index.js",
13 | "module": "index.js",
14 | "files": [
15 | "chameleon-hero.js",
16 | "/lib/"
17 | ],
18 | "scripts": {
19 | "test": "echo \"Error: run tests from root\" && exit 1",
20 | "build": "babel src --out-dir lib --config-file ../../babel.config.json"
21 | },
22 | "bugs": {
23 | "url": "https://github.com/MaritzSTL/chameleon/issues"
24 | },
25 | "dependencies": {
26 | "@chameleon-ds/skeleton": "^2.0.1",
27 | "lit-element": "^2.2.1"
28 | },
29 | "publishConfig": {
30 | "access": "public"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/packages/hero/src/ChameleonHero.js:
--------------------------------------------------------------------------------
1 | import { LitElement, html, property } from "lit-element";
2 | import { styleMap } from "lit-html/directives/style-map.js";
3 | import { nothing } from "lit-html";
4 | import { ChameleonHeroStyle } from "./ChameleonHeroStyle.js";
5 | import "@chameleon-ds/skeleton/chameleon-skeleton";
6 |
7 | export class ChameleonHero extends LitElement {
8 | /**
9 | * Properties
10 | */
11 | @property({ type: String })
12 | title = "";
13 |
14 | @property({ type: String })
15 | subTitle = "";
16 |
17 | @property({ type: String })
18 | heroText = "";
19 |
20 | @property({ type: String })
21 | imageUrl = "";
22 |
23 | @property({ type: String })
24 | type = "gradient";
25 |
26 | @property({ type: String })
27 | gradient = "var(--color-primary-dark), var(--color-secondary-dark)";
28 |
29 | @property({ type: Number })
30 | gradientAlpha = 0.5;
31 |
32 | @property({ type: Boolean })
33 | loading = false;
34 |
35 | /**
36 | * Styles
37 | */
38 | static styles = [ChameleonHeroStyle];
39 |
40 | /**
41 | * Template
42 | */
43 | render() {
44 | return html`
45 | ${this.loading
46 | ? html` `
47 | : html`
48 |
72 | `}
73 | `;
74 | }
75 |
76 | get backgroundImageStyles() {
77 | switch (this.type) {
78 | case "image-gradient":
79 | return {
80 | backgroundImage: `linear-gradient(to right, ${this.gradientOverlay}), url(${this.imageUrl})`,
81 | };
82 | case "gradient":
83 | return {
84 | backgroundImage: `linear-gradient(to right, ${this.gradientHex})`,
85 | };
86 | case "image":
87 | return {
88 | backgroundImage: `url(${this.imageUrl})`,
89 | };
90 | default:
91 | return {
92 | backgroundImage: `linear-gradient(to right, ${this.gradientHex})`,
93 | };
94 | }
95 | }
96 |
97 | get gradientHex() {
98 | return this.gradient.split(",").map((h) => h.trim());
99 | }
100 |
101 | get gradientOverlay() {
102 | return this.gradient
103 | .split(",")
104 | .map((h) => this.hex2rgba(h.trim(), this.gradientAlpha));
105 | }
106 |
107 | hex2rgba(hex, alpha = 0.5) {
108 | const [r, g, b] = hex.match(/\w\w/g).map((x) => parseInt(x, 16));
109 | return `rgba(${r},${g},${b},${alpha})`;
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/packages/hero/src/ChameleonHeroStyle.js:
--------------------------------------------------------------------------------
1 | import { css } from "lit-element";
2 |
3 | export const ChameleonHeroStyle = css`
4 | header {
5 | padding: 0 5em;
6 | }
7 |
8 | .hero {
9 | align-items: center;
10 | background-position: top;
11 | background-repeat: no-repeat;
12 | background-size: cover;
13 | display: flex;
14 | min-height: 400px;
15 | width: 100%;
16 | }
17 |
18 | .hero-title {
19 | font-size: var(--font-size-hero-title, 3rem);
20 | font-weight: normal;
21 | letter-spacing: -0.72px;
22 | margin: 0 0 8px;
23 | }
24 |
25 | .hero-subtitle {
26 | font-size: var(--font-size-hero-subtitle, 1.375rem);
27 | font-weight: normal;
28 | margin: 0 0 16px;
29 | }
30 |
31 | .hero-text {
32 | font-size: var(--font-size-paragraph-medium);
33 | letter-spacing: 0.25px;
34 | margin: 0;
35 | }
36 |
37 | .hero-title,
38 | .hero-subtitle,
39 | .hero-text {
40 | color: var(--color-hero-text, #ffffff);
41 | }
42 | `;
43 |
--------------------------------------------------------------------------------
/packages/input/chameleon-input.js:
--------------------------------------------------------------------------------
1 | import { ChameleonInput } from "./lib/ChameleonInput.js";
2 |
3 | customElements.define("chameleon-input", ChameleonInput);
4 |
--------------------------------------------------------------------------------
/packages/input/index.js:
--------------------------------------------------------------------------------
1 | export { ChameleonInput } from "./lib/ChameleonInput.js";
2 | export { ChameleonInputStyle } from "./lib/ChameleonInputStyle.js";
3 |
--------------------------------------------------------------------------------
/packages/input/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@chameleon-ds/input",
3 | "version": "2.0.1",
4 | "description": "Chameleon input",
5 | "author": "Maritz Motivation Solutions, Inc.",
6 | "license": "MIT",
7 | "homepage": "https://github.com/MaritzSTL/chameleon/tree/master/packages/input#readme",
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/MaritzSTL/chameleon.git"
11 | },
12 | "main": "index.js",
13 | "module": "index.js",
14 | "files": [
15 | "chameleon-input.js",
16 | "/lib/"
17 | ],
18 | "scripts": {
19 | "test": "echo \"Error: run tests from root\" && exit 1",
20 | "build": "babel src --out-dir lib --config-file ../../babel.config.json"
21 | },
22 | "bugs": {
23 | "url": "https://github.com/MaritzSTL/chameleon/issues"
24 | },
25 | "dependencies": {
26 | "lit-element": "^2.2.1"
27 | },
28 | "publishConfig": {
29 | "access": "public"
30 | },
31 | "gitHead": "0f8abecfe290971a220b969fc4d82fba4f6869ad"
32 | }
33 |
--------------------------------------------------------------------------------
/packages/input/src/ChameleonInputStyle.js:
--------------------------------------------------------------------------------
1 | import { css } from "lit-element";
2 |
3 | export const ChameleonInputStyle = css`
4 | :host {
5 | display: inline-block;
6 | font-family: var(--font-family, sans-serif);
7 | }
8 |
9 | .component-wrapper {
10 | display: inline-flex;
11 | flex-direction: column;
12 | width: 100%;
13 | }
14 |
15 | input {
16 | border: 1px solid var(--color-gray-light, #c4c7ca);
17 | border-radius: var(--border-radius-input, 0.313rem);
18 | box-sizing: border-box;
19 | font-size: var(--font-size-input, 0.938rem);
20 | font-family: var(--font-family, sans-serif);
21 | height: 100%;
22 | max-height: 40px;
23 | width: 100%;
24 | padding: var(--input-padding, 0.625rem 0.5rem);
25 | }
26 |
27 | .invalid input {
28 | border-color: var(--color-error, #bc1c16);
29 | }
30 |
31 | input:invalid {
32 | box-shadow: none;
33 | }
34 |
35 | .component-wrapper:hover:not(.invalid) input:not([disabled]),
36 | .component-wrapper:active:not(.invalid) input:not([disabled]) {
37 | border-color: var(--color-primary, #2c6fb7);
38 | }
39 |
40 | .label-row {
41 | display: flex;
42 | }
43 | .label-row.split-row {
44 | justify-content: space-between;
45 | }
46 | label,
47 | .label-row span {
48 | color: var(--color-gray-darkest, #6c737a);
49 | font-size: var(--font-size-label, 0.875rem);
50 | margin-bottom: 10px;
51 | }
52 |
53 | .component-wrapper.invalid .label-row span,
54 | label.invalid {
55 | color: var(--color-error, #bc1c16);
56 | }
57 |
58 | .label-row span {
59 | display: flex;
60 | align-items: flex-end;
61 | }
62 |
63 | .label-row span svg {
64 | padding-right: 3px;
65 | }
66 |
67 | .component-wrapper:hover:not(.invalid):not(.disabled) label,
68 | .component-wrapper:active:not(.invalid):not(.disabled) label,
69 | .component-wrapper:hover:not(.invalid):not(.disabled) .label-row span,
70 | .component-wrapper:active:not(.invalid):not(.disabled) .label-row span {
71 | color: var(--color-primary, #2c6fb7);
72 | }
73 |
74 | .error {
75 | color: var(--color-error, #bc1c16);
76 | font-size: var(--font-size-label, 0.875rem);
77 | margin-top: 3px;
78 | display: flex;
79 | align-items: center;
80 | }
81 |
82 | .error svg {
83 | padding-right: 0.5rem;
84 | }
85 |
86 | .input-wrapper {
87 | position: relative;
88 | }
89 |
90 | .input-wrapper.icon-left input {
91 | padding-left: 45px;
92 | }
93 |
94 | .input-wrapper.icon-right input {
95 | padding-right: 45px;
96 | }
97 |
98 | // We currently only support svg icons
99 | svg {
100 | width: 100%;
101 | height: 100%;
102 | color: var(--color-gray-darkest, #6c737a);
103 | }
104 |
105 | ::slotted(*) {
106 | color: var(--color-gray-darkest, #6c737a);
107 | height: 18px;
108 | position: absolute;
109 | top: 50%;
110 | transform: translateY(-50%);
111 | width: auto;
112 | }
113 |
114 | .invalid ::slotted(svg) {
115 | color: var(--color-error, #bc1c16);
116 | }
117 |
118 | ::slotted([slot="icon-left"]) {
119 | left: 13px;
120 | }
121 |
122 | ::slotted([slot="icon-right"]) {
123 | right: 13px;
124 | }
125 |
126 | .no-stepper input[type="number"]::-webkit-inner-spin-button,
127 | .no-stepper input[type="number"]::-webkit-outer-spin-button {
128 | -webkit-appearance: none;
129 | margin: 0;
130 | }
131 | .no-stepper input[type="number"] {
132 | -moz-appearance: textfield;
133 | }
134 | `;
135 |
--------------------------------------------------------------------------------
/packages/loader/README.md:
--------------------------------------------------------------------------------
1 | # Chameleon Loader
2 |
3 | ```js script
4 | import { html } from "@open-wc/demoing-storybook";
5 | import { withKnobs, text } from "@open-wc/demoing-storybook";
6 | import "./chameleon-loader.js";
7 |
8 | export default {
9 | title: "Components|Feedback/Loader",
10 | component: "chameleon-loader",
11 | decorators: [withKnobs],
12 | options: { selectedPanel: "storybookjs/docs/panel" },
13 | };
14 | ```
15 |
16 | ## Properties
17 |
18 | | Property Name | Type(s) | Default Value | Description |
19 | | ------------- | ------- | ------------- | ------------------------------------------ |
20 | | `loader` | String | `"spinner"` | The loader's style ("spinner", "ellipsis") |
21 | | `size` | String | `"auto"` | The loader's size |
22 |
23 | ## Examples
24 |
25 | ### Default
26 |
27 | ```js preview-story
28 | export const Default = () => {
29 | const size = text("Size", "21px");
30 |
31 | return html`
32 |
33 | `;
34 | };
35 | ```
36 |
37 | ### Ellipsis
38 |
39 | ```js preview-story
40 | export const Ellipsis = () => html`
41 |
42 | `;
43 | ```
44 |
--------------------------------------------------------------------------------
/packages/loader/__tests__/chameleon-loader.test.js:
--------------------------------------------------------------------------------
1 | import { fixture, html, expect } from "@open-wc/testing";
2 | import "../chameleon-loader.js";
3 |
4 | describe("chameleon-loader", () => {
5 | it("renders", async () => {
6 | const el = await fixture(html` `);
7 | expect(Boolean(el.shadowRoot)).to.equal(true);
8 | });
9 |
10 | it("renders a spinner by default", async () => {
11 | const el = await fixture(html` `);
12 | expect(Boolean(el.shadowRoot.querySelector(".spinner"))).to.equal(true);
13 | });
14 |
15 | it("renders a spinner", async () => {
16 | const el = await fixture(html`
17 |
18 | `);
19 | expect(Boolean(el.shadowRoot.querySelector(".spinner"))).to.equal(true);
20 | });
21 |
22 | it("renders an ellipsis", async () => {
23 | const el = await fixture(html`
24 |
25 | `);
26 | expect(Boolean(el.shadowRoot.querySelector(".ellipsis"))).to.equal(true);
27 | });
28 | });
29 |
--------------------------------------------------------------------------------
/packages/loader/chameleon-loader.js:
--------------------------------------------------------------------------------
1 | import { ChameleonLoader } from "./lib/ChameleonLoader.js";
2 |
3 | customElements.define("chameleon-loader", ChameleonLoader);
4 |
--------------------------------------------------------------------------------
/packages/loader/index.js:
--------------------------------------------------------------------------------
1 | export { ChameleonLoader } from "./lib/ChameleonLoader.js";
2 | export { ChameleonLoaderEllipsisStyle } from "./lib/ChameleonLoaderEllipsisStyle.js";
3 | export { ChameleonLoaderSpinnerStyle } from "./lib/ChameleonLoaderSpinnerStyle.js";
4 | export { ChameleonLoaderStyle } from "./lib/ChameleonLoaderStyle.js";
5 |
--------------------------------------------------------------------------------
/packages/loader/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@chameleon-ds/loader",
3 | "version": "2.0.1",
4 | "description": "Chameleon loader",
5 | "author": "Maritz Motivation Solutions, Inc.",
6 | "license": "MIT",
7 | "homepage": "https://github.com/MaritzSTL/chameleon/tree/master/packages/loader#readme",
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/MaritzSTL/chameleon.git"
11 | },
12 | "main": "index.js",
13 | "module": "index.js",
14 | "files": [
15 | "chameleon-loader.js",
16 | "/lib/"
17 | ],
18 | "scripts": {
19 | "test": "echo \"Error: run tests from root\" && exit 1",
20 | "build": "babel src --out-dir lib --config-file ../../babel.config.json"
21 | },
22 | "bugs": {
23 | "url": "https://github.com/MaritzSTL/chameleon/issues"
24 | },
25 | "dependencies": {
26 | "lit-element": "^2.2.1"
27 | },
28 | "publishConfig": {
29 | "access": "public"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/packages/loader/src/ChameleonLoader.js:
--------------------------------------------------------------------------------
1 | import { LitElement, html, property } from "lit-element";
2 | import { ChameleonLoaderStyle } from "./ChameleonLoaderStyle.js";
3 | import { ChameleonLoaderSpinnerStyle } from "./ChameleonLoaderSpinnerStyle.js";
4 | import { ChameleonLoaderEllipsisStyle } from "./ChameleonLoaderEllipsisStyle.js";
5 |
6 | export class ChameleonLoader extends LitElement {
7 | /**
8 | * Styles
9 | */
10 | static styles = [ChameleonLoaderStyle];
11 |
12 | @property({ type: String, reflect: true })
13 | loader = "spinner";
14 |
15 | @property({ type: String, reflect: true })
16 | size = "auto";
17 |
18 | /**
19 | * Template
20 | */
21 | render() {
22 | switch (this.loader) {
23 | case "ellipsis":
24 | return this.renderEllipsisLoader();
25 | case "spinner":
26 | default:
27 | return this.renderSpinnerLoader();
28 | }
29 | }
30 |
31 | renderEllipsisLoader() {
32 | return html`
33 |
36 |
37 |
43 | `;
44 | }
45 |
46 | renderSpinnerLoader() {
47 | return html`
48 |
51 |
52 |
59 |
60 |
61 | `;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/packages/loader/src/ChameleonLoaderEllipsisStyle.js:
--------------------------------------------------------------------------------
1 | import { css } from "lit-element";
2 |
3 | export const ChameleonLoaderEllipsisStyle = css`
4 | .ellipsis {
5 | display: inline-block;
6 | position: relative;
7 | width: 64px;
8 | height: 64px;
9 | }
10 |
11 | .ellipsis div {
12 | position: absolute;
13 | top: 27px;
14 | width: 11px;
15 | height: 11px;
16 | border-radius: 50%;
17 | background: var(--loader-color);
18 | animation-timing-function: cubic-bezier(0, 1, 1, 0);
19 | }
20 |
21 | .ellipsis div:nth-child(1) {
22 | left: 6px;
23 | animation: ellipsis1 0.6s infinite;
24 | }
25 |
26 | .ellipsis div:nth-child(2) {
27 | left: 6px;
28 | animation: ellipsis2 0.6s infinite;
29 | }
30 |
31 | .ellipsis div:nth-child(3) {
32 | left: 26px;
33 | animation: ellipsis2 0.6s infinite;
34 | }
35 |
36 | .ellipsis div:nth-child(4) {
37 | left: 45px;
38 | animation: ellipsis3 0.6s infinite;
39 | }
40 |
41 | @keyframes ellipsis1 {
42 | 0% {
43 | transform: scale(0);
44 | }
45 | 100% {
46 | transform: scale(1);
47 | }
48 | }
49 |
50 | @keyframes ellipsis3 {
51 | 0% {
52 | transform: scale(1);
53 | }
54 | 100% {
55 | transform: scale(0);
56 | }
57 | }
58 |
59 | @keyframes ellipsis2 {
60 | 0% {
61 | transform: translate(0, 0);
62 | }
63 | 100% {
64 | transform: translate(19px, 0);
65 | }
66 | }
67 | `;
68 |
--------------------------------------------------------------------------------
/packages/loader/src/ChameleonLoaderSpinnerStyle.js:
--------------------------------------------------------------------------------
1 | /* !
2 | * Materialize v1.0.0 (http://materializecss.com)
3 | * Copyright 2014-2017 Materialize
4 | * MIT License (https://raw.githubusercontent.com/Dogfalo/materialize/master/LICENSE)
5 | */
6 | import { css } from "lit-element";
7 |
8 | export const ChameleonLoaderSpinnerStyle = css`
9 | /* SVG styles. */
10 | svg {
11 | animation: 2s linear infinite svg-animation;
12 | }
13 |
14 | /* SVG animation. */
15 | @keyframes svg-animation {
16 | 0% {
17 | transform: rotateZ(0deg);
18 | }
19 | 100% {
20 | transform: rotateZ(360deg);
21 | }
22 | }
23 |
24 | /* Circle styles. */
25 | circle {
26 | animation: 1.4s ease-in-out infinite both circle-animation;
27 | display: block;
28 | fill: transparent;
29 | stroke: var(--loader-color, #2c6fb7);
30 | stroke-linecap: round;
31 | stroke-dasharray: 283;
32 | stroke-dashoffset: 280;
33 | stroke-width: 10px;
34 | transform-origin: 50% 50%;
35 | }
36 |
37 | /* Circle animation. */
38 | @keyframes circle-animation {
39 | 0%,
40 | 25% {
41 | stroke-dashoffset: 280;
42 | transform: rotate(0);
43 | }
44 |
45 | 50%,
46 | 75% {
47 | stroke-dashoffset: 75;
48 | transform: rotate(45deg);
49 | }
50 |
51 | 100% {
52 | stroke-dashoffset: 280;
53 | transform: rotate(360deg);
54 | }
55 | }
56 | `;
57 |
--------------------------------------------------------------------------------
/packages/loader/src/ChameleonLoaderStyle.js:
--------------------------------------------------------------------------------
1 | import { css } from "lit-element";
2 |
3 | export const ChameleonLoaderStyle = css`
4 | :host {
5 | box-sizing: border-box;
6 | --loader-color: var(--color-primary, #2c6fb7);
7 | }
8 |
9 | :host * {
10 | box-sizing: border-box;
11 | }
12 | `;
13 |
--------------------------------------------------------------------------------
/packages/modal/README.md:
--------------------------------------------------------------------------------
1 | # Chameleon Modal
2 |
3 | ```js script
4 | import { html } from "@open-wc/demoing-storybook";
5 | import "./chameleon-modal.js";
6 |
7 | export default {
8 | title: "Components|Overlays/Modal",
9 | component: "chameleon-modal",
10 | options: { selectedPanel: "storybookjs/docs/panel" },
11 | };
12 | ```
13 |
14 | ## Properties
15 |
16 | | Property Name | Type(s) | Default Value | Description |
17 | | ------------- | ------- | ------------- | ------------------------------------------- |
18 | | `open` | Boolean | `false` | If the modal is open |
19 | | `dismissible` | Boolean | `false` | If the modal is dismissible |
20 | | `fullScreen` | Boolean | `false` | Whether or not the modal appears fullscreen |
21 |
22 | ## Examples
23 |
24 | ### Default
25 |
26 | ```js preview-story
27 | export const Default = () => html`
28 |
29 | Contact Form
30 |
31 |
32 |
33 |
34 |
35 |
36 | Cancel
37 |
38 |
39 | Continue
40 |
41 |
42 | `;
43 | ```
44 |
--------------------------------------------------------------------------------
/packages/modal/__tests__/chameleon-modal.test.js:
--------------------------------------------------------------------------------
1 | import { litFixture, html, expect } from "@open-wc/testing";
2 | import sinon from "sinon";
3 | import "../chameleon-modal.js";
4 |
5 | const fixture = html` `;
6 |
7 | describe("chameleon-modal", () => {
8 | let element;
9 |
10 | beforeEach(async () => {
11 | element = await litFixture(fixture);
12 | });
13 |
14 | it("renders", () => {
15 | expect(Boolean(element.shadowRoot)).to.equal(true);
16 | });
17 |
18 | describe("_togglemodal", () => {
19 | it("should set open to true", () => {
20 | element.open = false;
21 | element._togglemodal();
22 |
23 | expect(element.open).to.be.true;
24 | });
25 |
26 | it("should set open to false", () => {
27 | element.open = true;
28 | element._togglemodal();
29 |
30 | expect(element.open).to.be.false;
31 | });
32 |
33 | it("should dispatch a toggle-modal event", () => {
34 | const spy = sinon.spy();
35 | element.addEventListener("toggle-modal", spy);
36 | element._togglemodal({});
37 | expect(spy).to.be.calledOnce;
38 | });
39 | });
40 |
41 | describe("closeIcon", () => {
42 | it("closeIcon returns an Svg if close-icon slot is defined", async () => {
43 | element = await litFixture(
44 | html` `
45 | );
46 | const closeIcon = await litFixture(element.closeIcon);
47 |
48 | expect(closeIcon).dom.to.equal(
49 | ` `
50 | );
51 | });
52 |
53 | it("closeIcon returns a slot if close-icon is undefined", async () => {
54 | element = await litFixture(
55 | html` `
56 | );
57 | const closeIcon = await litFixture(element.closeIcon);
58 |
59 | expect(closeIcon).dom.to.equal(" ");
60 | });
61 | });
62 | });
63 |
--------------------------------------------------------------------------------
/packages/modal/chameleon-modal.js:
--------------------------------------------------------------------------------
1 | import { ChameleonModal } from "./lib/ChameleonModal.js";
2 |
3 | customElements.define("chameleon-modal", ChameleonModal);
4 |
--------------------------------------------------------------------------------
/packages/modal/index.js:
--------------------------------------------------------------------------------
1 | export { ChameleonModal } from "./lib/ChameleonModal.js";
2 | export { ChameleonModalStyle } from "./lib/ChameleonModalStyle.js";
3 |
--------------------------------------------------------------------------------
/packages/modal/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@chameleon-ds/modal",
3 | "version": "1.0.1",
4 | "description": "Chameleon modal",
5 | "author": "Maritz Motivation Solutions, Inc.",
6 | "license": "MIT",
7 | "homepage": "https://github.com/MaritzSTL/chameleon/tree/master/packages/modal#readme",
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/MaritzSTL/chameleon.git"
11 | },
12 | "main": "index.js",
13 | "module": "index.js",
14 | "files": [
15 | "chameleon-modal.js",
16 | "/lib/"
17 | ],
18 | "scripts": {
19 | "test": "echo \"Error: run tests from root\" && exit 1",
20 | "build": "babel src --out-dir lib --config-file ../../babel.config.json"
21 | },
22 | "bugs": {
23 | "url": "https://github.com/MaritzSTL/chameleon/issues"
24 | },
25 | "dependencies": {
26 | "@chameleon-ds/button": "^2.0.1",
27 | "@chameleon-ds/card": "^2.0.1",
28 | "lit-element": "^2.2.1"
29 | },
30 | "publishConfig": {
31 | "access": "public"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/packages/modal/src/ChameleonModal.js:
--------------------------------------------------------------------------------
1 | import { LitElement, html, property } from "lit-element";
2 | import { nothing, svg } from "lit-html";
3 | import { classMap } from "lit-html/directives/class-map";
4 | import { ChameleonModalStyle } from "./ChameleonModalStyle.js";
5 | import "@chameleon-ds/card/chameleon-card";
6 | import "@chameleon-ds/button/chameleon-button";
7 |
8 | export class ChameleonModal extends LitElement {
9 | /**
10 | * Properties
11 | */
12 | @property({ type: Boolean, reflect: true })
13 | open = false;
14 |
15 | // Card has a close icon
16 | @property({ type: Boolean, reflect: true })
17 | dismissible = false;
18 |
19 | @property({ type: Boolean, reflect: true })
20 | fullScreen = false;
21 |
22 | /**
23 | * Styles
24 | */
25 | static styles = [ChameleonModalStyle];
26 |
27 | /**
28 | * Template
29 | */
30 | render() {
31 | return html`
32 |
39 |
40 |
55 |
56 |
57 |
58 |
62 |
63 |
64 | `;
65 | }
66 |
67 | _togglemodal() {
68 | this.open = !this.open;
69 | const e = new CustomEvent("toggle-modal", {
70 | bubbles: true,
71 | composed: true,
72 | });
73 | this.dispatchEvent(e);
74 | }
75 |
76 | get closeIcon() {
77 | const slots = Array.from(this.querySelectorAll("[slot]"));
78 | const closeIcon = slots.find((slot) => slot.slot === "close-icon");
79 |
80 | if (closeIcon === undefined)
81 | return svg` `;
82 | else return html` `;
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/packages/modal/src/ChameleonModalStyle.js:
--------------------------------------------------------------------------------
1 | import { css } from "lit-element";
2 |
3 | export const ChameleonModalStyle = css`
4 | .open {
5 | display: flex;
6 | }
7 |
8 | .close {
9 | display: none;
10 | }
11 |
12 | ::slotted([slot="body"]) {
13 | display: grid;
14 | grid-template-rows: auto;
15 | grid-column-gap: 20px;
16 | grid-row-gap: 20px;
17 | grid-template-columns: repeat(2, 1fr);
18 | }
19 |
20 | .header {
21 | display: grid;
22 | max-height: 80px;
23 | grid-template-rows: auto;
24 | grid-column-gap: 1rem;
25 | grid-template-columns: 1fr;
26 | }
27 |
28 | .footer {
29 | display: grid;
30 | grid-template-rows: auto;
31 | grid-column-gap: 20px;
32 | grid-row-gap: 20px;
33 | grid-template-columns: repeat(10, 1fr);
34 | }
35 |
36 | .header {
37 | border-bottom: 1px var(--color-gray-light, #c4c7ca) solid;
38 | padding: 30px 30px;
39 | }
40 |
41 | .footer {
42 | padding: 0 30px 30px;
43 | }
44 |
45 | .overlay {
46 | width: 100vw;
47 | height: 100vh;
48 | background-color: rgba(0, 0, 0, 0.4);
49 | position: fixed;
50 | top: 0;
51 | right: 0;
52 | bottom: 0;
53 | left: 0;
54 | z-index: 9999;
55 | }
56 |
57 | chameleon-card {
58 | flex-direction: column;
59 | border-top: solid var(--color-secondary) 10px;
60 | position: absolute;
61 | left: 50%;
62 | top: 50%;
63 | padding: 0px !important;
64 | transform: translate(-50%, -50%);
65 | border-radius: 5px;
66 | box-shadow: 0 8px 16px 0 rgba(12, 0, 51, 0.1);
67 | margin: auto;
68 | background-color: #ffffff;
69 | width: 600px;
70 | padding: 30px;
71 | animation-name: modalopen;
72 | animation-duration: 1s;
73 | }
74 |
75 | .full-screen {
76 | border-radius: unset;
77 | position: relative;
78 | width: 100%;
79 | margin-bottom: 0;
80 | margin-top: 0;
81 | }
82 |
83 | .close-icon {
84 | cursor: pointer;
85 | grid-column: 10 / span 1;
86 | justify-self: right;
87 | }
88 |
89 | ::slotted([slot="right-button"]) {
90 | cursor: pointer;
91 | grid-column: 9 / span 2;
92 | }
93 |
94 | @media (max-width: 480px) {
95 | ::slotted([slot="right-button"]) {
96 | grid-column: 8 / span 3;
97 | }
98 | }
99 |
100 | svg {
101 | height: 24px;
102 | color: var(--color-gray-darkest);
103 | }
104 |
105 | ::slotted(h3) {
106 | color: var(--color-primary-dark, #004587);
107 | margin: 0;
108 | }
109 |
110 | ::slotted(h3, [slot="title"]),
111 | ::slotted([slot="left-button"]) {
112 | color: var(--color-primary-dark, #004587);
113 | height: 19px;
114 | font-family: Lato;
115 | font-size: 18px;
116 | font-weight: normal;
117 | font-stretch: normal;
118 | font-style: normal;
119 | line-height: 1.17;
120 | letter-spacing: normal;
121 | margin: 0;
122 | }
123 |
124 | ::slotted([slot="body"]) {
125 | padding: 20px 30px 40px;
126 | }
127 |
128 | @keyframes modalopen {
129 | from {
130 | opacity: 0;
131 | }
132 | to {
133 | opacity: 1;
134 | }
135 | }
136 | `;
137 |
--------------------------------------------------------------------------------
/packages/multiselect/chameleon-multiselect.js:
--------------------------------------------------------------------------------
1 | import { ChameleonMultiselect } from "./lib/ChameleonMultiselect.js";
2 |
3 | customElements.define("chameleon-multiselect", ChameleonMultiselect);
4 |
--------------------------------------------------------------------------------
/packages/multiselect/index.js:
--------------------------------------------------------------------------------
1 | export { ChameleonMultiselect } from "./lib/ChameleonMultiselect.js";
2 | export { ChameleonMultiselectStyle } from "./lib/ChameleonMultiselectStyle.js";
3 |
--------------------------------------------------------------------------------
/packages/multiselect/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@chameleon-ds/multiselect",
3 | "version": "2.0.1",
4 | "description": "Chameleon multiselect",
5 | "author": "Maritz Motivation Solutions, Inc.",
6 | "license": "MIT",
7 | "homepage": "https://github.com/MaritzSTL/chameleon/tree/master/packages/multiselect#readme",
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/MaritzSTL/chameleon.git"
11 | },
12 | "main": "index.js",
13 | "module": "index.js",
14 | "files": [
15 | "chameleon-multiselect.js",
16 | "/lib/"
17 | ],
18 | "scripts": {
19 | "test": "echo \"Error: run tests from root\" && exit 1",
20 | "build": "babel src --out-dir lib --config-file ../../babel.config.json"
21 | },
22 | "bugs": {
23 | "url": "https://github.com/MaritzSTL/chameleon/issues"
24 | },
25 | "dependencies": {
26 | "@chameleon-ds/chip": "^2.0.1",
27 | "@chameleon-ds/loader": "^2.0.1",
28 | "lit-element": "^2.2.1"
29 | },
30 | "publishConfig": {
31 | "access": "public"
32 | },
33 | "gitHead": "0f8abecfe290971a220b969fc4d82fba4f6869ad"
34 | }
35 |
--------------------------------------------------------------------------------
/packages/paginator/README.md:
--------------------------------------------------------------------------------
1 | # Chameleon Pagniator
2 |
3 | ```js script
4 | import { html } from "@open-wc/demoing-storybook";
5 | import { withKnobs, number } from "@open-wc/demoing-storybook";
6 | import "./chameleon-paginator.js";
7 |
8 | export default {
9 | title: "Components|Navigation/Paginator",
10 | component: "chameleon-paginator",
11 | decorators: [withKnobs],
12 | options: { selectedPanel: "storybookjs/docs/panel" },
13 | };
14 | ```
15 |
16 | ## Properties
17 |
18 | | Property Name | Type(s) | Default Value | Description |
19 | | ------------- | ------- | ------------- | -------------------------------------- |
20 | | `totalItems` | Number | `null` | The total number of items in all pages |
21 | | `pageSize` | Number | `null` | The amount of pages of items |
22 | | `currentPage` | Number | `1` | The multiselect's current page |
23 | | `maxLength` | Number | `7` | The max length of visible pages |
24 | | `separator` | String | `"..."` | The separator for skipped pages |
25 |
26 | ## Examples
27 |
28 | ### Default
29 |
30 | ```js preview-story
31 | export const Default = () => {
32 | const totalItems = number("Total Items", 100);
33 | const pageSize = number("Page Size", 10);
34 |
35 | return html`
36 |
40 | `;
41 | };
42 | ```
43 |
--------------------------------------------------------------------------------
/packages/paginator/chameleon-paginator.js:
--------------------------------------------------------------------------------
1 | import { ChameleonPaginator } from "./lib/ChameleonPaginator.js";
2 |
3 | customElements.define("chameleon-paginator", ChameleonPaginator);
4 |
--------------------------------------------------------------------------------
/packages/paginator/index.js:
--------------------------------------------------------------------------------
1 | export { ChameleonPaginator } from "./lib/ChameleonPaginator.js";
2 | export { ChameleonPaginatorStyle } from "./lib/ChameleonPaginatorStyle.js";
3 |
--------------------------------------------------------------------------------
/packages/paginator/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@chameleon-ds/paginator",
3 | "version": "2.0.1",
4 | "description": "Chameleon paginator",
5 | "author": "Maritz Motivation Solutions, Inc.",
6 | "license": "MIT",
7 | "homepage": "https://github.com/MaritzSTL/chameleon/tree/master/packages/paginator#readme",
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/MaritzSTL/chameleon.git"
11 | },
12 | "main": "index.js",
13 | "module": "index.js",
14 | "files": [
15 | "chameleon-paginator.js",
16 | "/lib/"
17 | ],
18 | "scripts": {
19 | "test": "echo \"Error: run tests from root\" && exit 1",
20 | "build": "babel src --out-dir lib --config-file ../../babel.config.json"
21 | },
22 | "bugs": {
23 | "url": "https://github.com/MaritzSTL/chameleon/issues"
24 | },
25 | "dependencies": {
26 | "@chameleon-ds/button": "^2.0.1",
27 | "lit-element": "^2.2.1"
28 | },
29 | "publishConfig": {
30 | "access": "public"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/packages/paginator/src/ChameleonPaginatorStyle.js:
--------------------------------------------------------------------------------
1 | import { css } from "lit-element";
2 |
3 | export const ChameleonPaginatorStyle = css`
4 | :host {
5 | align-items: center;
6 | display: flex;
7 | }
8 |
9 | .pages {
10 | list-style: none;
11 | margin: 0;
12 | padding: 0;
13 | }
14 |
15 | .page {
16 | box-sizing: border-box;
17 | cursor: pointer;
18 | display: inline-block;
19 | margin: 18px;
20 | }
21 |
22 | .page a {
23 | color: var(--color-primary, #2c6fb7);
24 | }
25 |
26 | .separator {
27 | cursor: auto;
28 | margin: 14px;
29 | }
30 |
31 | .current,
32 | .page:not(.separator):hover {
33 | color: var(--color-surface, #ffffff);
34 | margin: 0 4px;
35 | }
36 |
37 | a {
38 | text-decoration: none;
39 | }
40 |
41 | .current a,
42 | .page a:not(.separator):hover {
43 | align-items: center;
44 | background-color: var(--color-primary, #2c6fb7);
45 | color: var(--color-surface, #ffffff);
46 | border-radius: 50%;
47 | display: inline-flex;
48 | height: 36px;
49 | justify-content: center;
50 | width: 36px;
51 | }
52 |
53 | .placeholder {
54 | width: 68px;
55 | }
56 | `;
57 |
--------------------------------------------------------------------------------
/packages/progress-bar/README.md:
--------------------------------------------------------------------------------
1 | # Chameleon Progress Bar
2 |
3 | ```js script
4 | import { html } from "@open-wc/demoing-storybook";
5 | import { withKnobs, number, text } from "@open-wc/demoing-storybook";
6 | import "./chameleon-progress-bar.js";
7 |
8 | export default {
9 | title: "Components|Status/Progress Bar",
10 | component: "chameleon-progress-bar",
11 | decorators: [withKnobs],
12 | options: { selectedPanel: "storybookjs/docs/panel" },
13 | };
14 | ```
15 |
16 | ## Properties
17 |
18 | | Property Name | Type(s) | Default Value | Description |
19 | | ------------- | ------- | ------------- | -------------------------------------- |
20 | | `percent` | Number | `undefined` | The total number of items in all pages |
21 | | `total` | Number | `0` | The amount of pages of items |
22 | | `completed` | Number | `0` | The multiselect's current page |
23 | | `label` | String | `""` | The max length of visible pages |
24 |
25 | ## Examples
26 |
27 | ### Default
28 |
29 | ```js preview-story
30 | export const Default = () => {
31 | const percent = number("Percent", 75);
32 | const label = text("Label", "Processing...");
33 |
34 | return html`
35 |
36 |
37 | `;
38 | };
39 | ```
40 |
--------------------------------------------------------------------------------
/packages/progress-bar/__tests__/chameleon-progress-bar.test.js:
--------------------------------------------------------------------------------
1 | import { fixture, html, expect } from "@open-wc/testing";
2 | import "../chameleon-progress-bar.js";
3 |
4 | describe("chameleon-progress-bar", () => {
5 | it("renders", async () => {
6 | const el = await fixture(html`
7 |
8 | `);
9 | expect(Boolean(el.shadowRoot)).to.equal(true);
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/packages/progress-bar/chameleon-progress-bar.js:
--------------------------------------------------------------------------------
1 | import { ChameleonProgressBar } from "./lib/ChameleonProgressBar.js";
2 |
3 | customElements.define("chameleon-progress-bar", ChameleonProgressBar);
4 |
--------------------------------------------------------------------------------
/packages/progress-bar/index.js:
--------------------------------------------------------------------------------
1 | export { ChameleonProgressBar } from "./lib/ChameleonProgressBar.js";
2 | export { ChameleonProgressBarStyle } from "./lib/ChameleonProgressBarStyle.js";
3 |
--------------------------------------------------------------------------------
/packages/progress-bar/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@chameleon-ds/progress-bar",
3 | "version": "1.0.1",
4 | "description": "Chameleon progress bar",
5 | "author": "Maritz Motivation Solutions, Inc.",
6 | "license": "MIT",
7 | "homepage": "https://github.com/MaritzSTL/chameleon/tree/master/packages/progress-bar#readme",
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/MaritzSTL/chameleon.git"
11 | },
12 | "main": "index.js",
13 | "module": "index.js",
14 | "files": [
15 | "chameleon-progress-bar.js",
16 | "/lib/"
17 | ],
18 | "scripts": {
19 | "test": "echo \"Error: run tests from root\" && exit 1",
20 | "build": "babel src --out-dir lib --config-file ../../babel.config.json"
21 | },
22 | "bugs": {
23 | "url": "https://github.com/MaritzSTL/chameleon/issues"
24 | },
25 | "dependencies": {
26 | "lit-element": "^2.2.1"
27 | },
28 | "publishConfig": {
29 | "access": "public"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/packages/progress-bar/src/ChameleonProgressBar.js:
--------------------------------------------------------------------------------
1 | import { LitElement, html, property } from "lit-element";
2 | import { ChameleonProgressBarStyle } from "./ChameleonProgressBarStyle.js";
3 |
4 | export class ChameleonProgressBar extends LitElement {
5 | /**
6 | * Properties
7 | */
8 | @property({ type: Number, reflect: true })
9 | percent = undefined;
10 |
11 | @property({ type: Number, reflect: true })
12 | total = 0;
13 |
14 | @property({ type: Number, reflect: true })
15 | completed = 0;
16 |
17 | @property({ type: String, reflect: true })
18 | label = "";
19 |
20 | /**
21 | * Styles
22 | */
23 | static styles = [ChameleonProgressBarStyle];
24 |
25 | /**
26 | * Template
27 | */
28 | render() {
29 | return html`
30 |
31 |
41 |
42 | ${this.total > 0 ? this.completed : ""}
43 |
44 |
45 | ${this.total > 0
46 | ? " of " + this.total + " " + this.label
47 | : this.label}
48 |
49 |
50 | `;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/packages/progress-bar/src/ChameleonProgressBarStyle.js:
--------------------------------------------------------------------------------
1 | import { css } from "lit-element";
2 |
3 | export const ChameleonProgressBarStyle = css`
4 | :host {
5 | display: inline-flex;
6 | }
7 |
8 | .progress-bar-container {
9 | width: 100%;
10 | }
11 |
12 | .background {
13 | height: 12px;
14 | position: relative;
15 | background-color: rgba(44, 111, 183, 0.05);
16 | padding: 4px 6px;
17 | border-radius: 3px;
18 | }
19 |
20 | .progress-bar {
21 | height: 12px;
22 | background-color: rgba(44, 111, 183, 1);
23 | border-radius: 3px;
24 | }
25 |
26 | label {
27 | font-family: var(--font-family, sans-serif);
28 | font-size: var(--font-size-label, 0.875rem);
29 | }
30 |
31 | .total-item-label {
32 | font-weight: bold;
33 | color: rgba(44, 111, 183, 1);
34 | }
35 | `;
36 |
--------------------------------------------------------------------------------
/packages/radio/README.md:
--------------------------------------------------------------------------------
1 | # Chameleon Radio
2 |
3 | ```js script
4 | import { html } from "@open-wc/demoing-storybook";
5 | import { withKnobs, text, boolean } from "@open-wc/demoing-storybook";
6 | import "./chameleon-radio.js";
7 |
8 | export default {
9 | title: "Components|Form Elements/Radio",
10 | component: "chameleon-radio",
11 | decorators: [withKnobs],
12 | options: { selectedPanel: "storybookjs/docs/panel" },
13 | };
14 | ```
15 |
16 | ## Properties
17 |
18 | | Property Name | Type(s) | Default Value | Description |
19 | | ------------- | ------- | ------------- | ------------------------------------------------------------------------------------ |
20 | | `label` | String | `""` | The radio's label |
21 | | `name` | String | `"cha-radio"` | The radio's form name |
22 | | `checked` | Boolean | `false` | A Boolean which, if true, indicates that the radio is selected |
23 | | `value` | String | `""` | The radio's current value |
24 | | `disabled` | Boolean | `false` | A Boolean to disable radio button |
25 | | `readonly` | Boolean | `false` | A Boolean attribute which, if true, indicates that the radio button cannot be edited |
26 | | `invalid` | Boolean | `false` | Invalid boolean to allow validity access from higher level form errors |
27 |
28 | ## Examples
29 |
30 | ### Default
31 |
32 | ```js preview-story
33 | export const Default = () => {
34 | const label = text("Label", "");
35 | const checked = boolean("Checked", true);
36 | const disabled = boolean("Disabled", false);
37 | const invalid = boolean("Invalid", false);
38 |
39 | return html`
40 |
46 | `;
47 | };
48 | ```
49 |
--------------------------------------------------------------------------------
/packages/radio/__tests__/chameleon-radio.test.js:
--------------------------------------------------------------------------------
1 | import { litFixture, html, expect } from "@open-wc/testing";
2 | import "../chameleon-radio.js";
3 |
4 | const fixture = html` `;
5 |
6 | describe("chameleon-radio", () => {
7 | let element;
8 |
9 | beforeEach(async () => {
10 | element = await litFixture(fixture);
11 | });
12 |
13 | it("renders", () => {
14 | expect(Boolean(element.shadowRoot)).to.equal(true);
15 | });
16 |
17 | it("shows aria-invalid when invalid", () => {
18 | element.invalid = true;
19 | expect(element).shadowDom.to.equalSnapshot();
20 | });
21 | it("shows name attribute", () => {
22 | element.name = "formName";
23 | expect(element).shadowDom.to.equalSnapshot();
24 | });
25 | it("shows disabled attribute", () => {
26 | element.required = true;
27 | expect(element).shadowDom.to.equalSnapshot();
28 | });
29 | it("shows readonly attribute", () => {
30 | element.readonly = true;
31 | expect(element).shadowDom.to.equalSnapshot();
32 | });
33 |
34 | it("renders labelText", () => {
35 | element.label = "chameleon";
36 |
37 | expect(element.labelText).to.equal("chameleon");
38 | });
39 | });
40 |
--------------------------------------------------------------------------------
/packages/radio/chameleon-radio.js:
--------------------------------------------------------------------------------
1 | import { ChameleonRadio } from "./lib/ChameleonRadio.js";
2 |
3 | customElements.define("chameleon-radio", ChameleonRadio);
4 |
--------------------------------------------------------------------------------
/packages/radio/index.js:
--------------------------------------------------------------------------------
1 | export { ChameleonRadio } from "./lib/ChameleonRadio.js";
2 | export { ChameleonRadioStyle } from "./lib/ChameleonRadioStyle.js";
3 |
--------------------------------------------------------------------------------
/packages/radio/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@chameleon-ds/radio",
3 | "version": "2.0.1",
4 | "description": "Chameleon radio",
5 | "author": "Maritz Motivation Solutions, Inc.",
6 | "license": "MIT",
7 | "homepage": "https://github.com/MaritzSTL/chameleon/tree/master/packages/radio#readme",
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/MaritzSTL/chameleon.git"
11 | },
12 | "main": "index.js",
13 | "module": "index.js",
14 | "files": [
15 | "chameleon-radio.js",
16 | "/lib/"
17 | ],
18 | "scripts": {
19 | "test": "echo \"Error: run tests from root\" && exit 1",
20 | "build": "babel src --out-dir lib --config-file ../../babel.config.json"
21 | },
22 | "bugs": {
23 | "url": "https://github.com/MaritzSTL/chameleon/issues"
24 | },
25 | "dependencies": {
26 | "lit-element": "^2.2.1"
27 | },
28 | "publishConfig": {
29 | "access": "public"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/packages/radio/src/ChameleonRadio.js:
--------------------------------------------------------------------------------
1 | import { LitElement, html, property } from "lit-element";
2 | import { nothing } from "lit-html";
3 | import { ChameleonRadioStyle } from "./ChameleonRadioStyle.js";
4 |
5 | export class ChameleonRadio extends LitElement {
6 | /**
7 | * Properties
8 | */
9 |
10 | // The radio's label
11 | @property({ type: String })
12 | label = "";
13 |
14 | @property({ type: String })
15 | name = "cha-radio";
16 |
17 | // A Boolean which, if true, indicates that the radio is selected
18 | @property({ type: Boolean, reflect: true })
19 | checked = false;
20 |
21 | // The radio's current value
22 | @property({ type: String })
23 | value = "";
24 |
25 | // A Boolean to disable radio button
26 | @property({ type: Boolean, reflect: true })
27 | disabled = false;
28 |
29 | // A Boolean attribute which, if true, indicates that the radio button cannot be edited
30 | @property({ type: Boolean, reflect: true })
31 | readonly = false;
32 |
33 | // Invalid boolean to allow validity access from higher level form errors
34 | @property({ type: Boolean, reflect: true })
35 | invalid = false;
36 |
37 | /**
38 | * Styles
39 | */
40 | static styles = [ChameleonRadioStyle];
41 |
42 | /**
43 | * Template
44 | */
45 | render() {
46 | return html`
47 |
57 |
58 | ${this.labelText}
59 | `;
60 | }
61 |
62 | get labelText() {
63 | if (this.label !== "") return this.label;
64 | else return nothing;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/packages/radio/src/ChameleonRadioStyle.js:
--------------------------------------------------------------------------------
1 | import { css } from "lit-element";
2 |
3 | export const ChameleonRadioStyle = css`
4 | :host {
5 | align-items: center;
6 | cursor: pointer;
7 | display: inline-flex;
8 | font-size: var(--font-size-input, 0.938rem);
9 | -webkit-user-select: none;
10 | -moz-user-select: none;
11 | -ms-user-select: none;
12 | user-select: none;
13 | }
14 |
15 | input {
16 | cursor: pointer;
17 | display: none;
18 | }
19 |
20 | .checkmark {
21 | background-color: var(--color-surface, #ffffff);
22 | border: 2px solid var(--color-gray-lightest, #e1e3e4);
23 | border-radius: 50%;
24 | box-sizing: border-box;
25 | display: inline-block;
26 | height: 20px;
27 | margin-right: 10px;
28 | position: relative;
29 | width: 20px;
30 | }
31 |
32 | :host:hover input ~ .checkmark {
33 | background-color: var(--color-surface, #ffffff);
34 | }
35 |
36 | input:checked ~ .checkmark {
37 | background-color: var(--color-primary, #2c6fb7);
38 | border: none;
39 | }
40 |
41 | .checkmark:after {
42 | content: "";
43 | display: none;
44 | position: absolute;
45 | }
46 |
47 | input:checked ~ .checkmark:after {
48 | display: block;
49 | }
50 |
51 | .checkmark:after {
52 | background: var(--color-surface, #ffffff);
53 | border-radius: 50%;
54 | height: 8px;
55 | left: 50%;
56 | top: 50%;
57 | transform: translate(-50%, -50%);
58 | width: 8px;
59 | }
60 | :host([invalid]) .checkmark {
61 | border-color: var(--color-error, #bc1c16);
62 | }
63 |
64 | :host([invalid]) input:checked ~ .checkmark {
65 | border: 2px solid var(--color-error, #bc1c16);
66 | }
67 |
68 | :host([readonly]),
69 | :host([disabled]),
70 | input[disabled] {
71 | pointer-events: none;
72 | }
73 |
74 | input:checked ~ .checkmark.disabled {
75 | background-color: var(--color-gray-lightest, #e1e3e4);
76 | pointer-events: none;
77 | }
78 | `;
79 |
--------------------------------------------------------------------------------
/packages/select/chameleon-select.js:
--------------------------------------------------------------------------------
1 | import { ChameleonSelect } from "./lib/ChameleonSelect.js";
2 |
3 | customElements.define("chameleon-select", ChameleonSelect);
4 |
--------------------------------------------------------------------------------
/packages/select/index.js:
--------------------------------------------------------------------------------
1 | export { ChameleonSelect } from "./lib/ChameleonSelect.js";
2 | export { ChameleonSelectStyle } from "./lib/ChameleonSelectStyle.js";
3 |
--------------------------------------------------------------------------------
/packages/select/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@chameleon-ds/select",
3 | "version": "2.0.2",
4 | "description": "Chameleon select",
5 | "author": "Maritz Motivation Solutions, Inc.",
6 | "license": "MIT",
7 | "homepage": "https://github.com/MaritzSTL/chameleon/tree/master/packages/select#readme",
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/MaritzSTL/chameleon.git"
11 | },
12 | "main": "index.js",
13 | "module": "index.js",
14 | "files": [
15 | "chameleon-select.js",
16 | "/lib/"
17 | ],
18 | "scripts": {
19 | "test": "echo \"Error: run tests from root\" && exit 1",
20 | "build": "babel src --out-dir lib --config-file ../../babel.config.json"
21 | },
22 | "bugs": {
23 | "url": "https://github.com/MaritzSTL/chameleon/issues"
24 | },
25 | "dependencies": {
26 | "lit-element": "^2.2.0"
27 | },
28 | "publishConfig": {
29 | "access": "public"
30 | },
31 | "gitHead": "0f8abecfe290971a220b969fc4d82fba4f6869ad"
32 | }
33 |
--------------------------------------------------------------------------------
/packages/sheet/__tests__/chameleon-sheet.test.js:
--------------------------------------------------------------------------------
1 | import { litFixture, html, expect } from "@open-wc/testing";
2 | import "../chameleon-sheet.js";
3 | import "../sheet-content.js";
4 |
5 | describe("chameleon-sheet", () => {
6 | let el;
7 | beforeEach(async () => {
8 | el = await litFixture(html`
9 |
10 | content
11 | invoker
12 |
13 | `);
14 | });
15 |
16 | it("is not opened by default", () => {
17 | expect(el.opened).not.to.equal(true);
18 | });
19 | it("opens when invoker is clicked", async () => {
20 | const invoker = el.querySelector("[slot='invoker']");
21 | invoker.click();
22 | await el.updateComplete;
23 | expect(el.opened).to.equal(true);
24 | });
25 | it("relocates content slot", () => {
26 | const globalRootNode = document.body.querySelector(".global-overlays");
27 | const relocatedNode = globalRootNode.lastChild;
28 | expect(relocatedNode.innerHTML).to.equal(
29 | `content
`
30 | );
31 | });
32 | });
33 |
--------------------------------------------------------------------------------
/packages/sheet/__tests__/sheet-content.test.js:
--------------------------------------------------------------------------------
1 | import { litFixture, html, expect } from "@open-wc/testing";
2 | import "../chameleon-sheet.js";
3 | import "../sheet-content.js";
4 |
5 | describe("sheet-content", () => {
6 | let el;
7 | beforeEach(async () => {
8 | el = await litFixture(html`
9 |
10 | content
11 |
12 | `);
13 | });
14 |
15 | it("has customizable width", async () => {
16 | expect(el.width).to.equal("320px");
17 | el.width = "75vw";
18 | await el.updateComplete;
19 | const styleNode = el.shadowRoot.querySelector("style");
20 | expect(styleNode.textContent.includes("75vw")).to.equal(true);
21 | });
22 | it("maintains width-per-instance", async () => {
23 | const el2 = await litFixture(html`
24 |
25 | content
26 |
27 | `);
28 | const styleNode = el.shadowRoot.querySelector("style");
29 | const styleNode2 = el2.shadowRoot.querySelector("style");
30 | expect(el.width).to.equal("320px");
31 | expect(styleNode.textContent.includes("320px")).to.equal(true);
32 | expect(el2.width).to.equal(`75vw`);
33 | expect(styleNode2.textContent.includes("75vw")).to.equal(true);
34 | });
35 | it("accepts default slotted content", () => {
36 | const assignedElement = el.querySelector("#myContent");
37 | const slot = el.shadowRoot.querySelector("slot");
38 | expect(slot.assignedElements().includes(assignedElement)).to.equal(true);
39 | });
40 | it("is dismissable by default", () => {
41 | expect(el.dismissable).to.equal(true);
42 | });
43 | it("displays close icon when dismissable", () => {
44 | expect(
45 | el.shadowRoot.querySelector(".close-icon").innerHTML.includes("svg")
46 | ).to.equal(true);
47 | expect(el.shadowRoot.querySelector(".close-icon")).to.not.equal(null);
48 | });
49 | it("doesn't show close icon when not dismissable", async () => {
50 | el.dismissable = false;
51 | await el.updateComplete;
52 | expect(el.shadowRoot.querySelector(".close-icon")).to.equal(null);
53 | });
54 | it("close icon dispatches close-overlay event when clicked", () => {
55 | let called = false;
56 | const listener = (e) => {
57 | called = true;
58 | };
59 | el.addEventListener("close-overlay", listener);
60 | el.shadowRoot.querySelector(".close-icon").click();
61 | expect(called).to.equal(true);
62 | });
63 | });
64 |
--------------------------------------------------------------------------------
/packages/sheet/chameleon-sheet.js:
--------------------------------------------------------------------------------
1 | import { ChameleonSheet } from "./lib/ChameleonSheet.js";
2 |
3 | customElements.define("chameleon-sheet", ChameleonSheet);
4 |
--------------------------------------------------------------------------------
/packages/sheet/index.js:
--------------------------------------------------------------------------------
1 | export { ChameleonSheet } from "./lib/ChameleonSheet.js";
2 | export { SheetContent } from "./lib/SheetContent.js";
3 |
--------------------------------------------------------------------------------
/packages/sheet/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@chameleon-ds/sheet",
3 | "version": "3.0.2",
4 | "description": "Chameleon sheet",
5 | "author": "Maritz Motivation Solutions, Inc.",
6 | "license": "MIT",
7 | "homepage": "https://github.com/MaritzSTL/chameleon/tree/master/packages/sheet#readme",
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/MaritzSTL/chameleon.git"
11 | },
12 | "main": "index.js",
13 | "module": "index.js",
14 | "files": [
15 | "chameleon-sheet.js",
16 | "sheet-content.js",
17 | "/lib/"
18 | ],
19 | "scripts": {
20 | "test": "echo \"Error: run tests from root\" && exit 1",
21 | "build": "babel src --out-dir lib --config-file ../../babel.config.json"
22 | },
23 | "bugs": {
24 | "url": "https://github.com/MaritzSTL/chameleon/issues"
25 | },
26 | "dependencies": {
27 | "@chameleon-ds/button": "^2.0.1",
28 | "@lion/overlays": "0.16.0",
29 | "lit-element": "^2.2.1"
30 | },
31 | "publishConfig": {
32 | "access": "public"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/packages/sheet/sheet-content.js:
--------------------------------------------------------------------------------
1 | import { SheetContent } from "./lib/SheetContent.js";
2 |
3 | customElements.define("sheet-content", SheetContent);
4 |
--------------------------------------------------------------------------------
/packages/sheet/src/ChameleonSheet.js:
--------------------------------------------------------------------------------
1 | import { OverlayMixin } from "@lion/overlays";
2 | import { LitElement, html, property } from "lit-element";
3 |
4 | export class ChameleonSheet extends OverlayMixin(LitElement) {
5 | __toggle;
6 |
7 | @property({ type: Boolean }) trapsKeyboardFocus = true;
8 | @property({ type: Boolean }) hasBackdrop = true;
9 | @property({ type: Boolean }) hidesOnOutsideClick = true;
10 | @property({ type: Boolean }) hidesOnEsc = true;
11 | @property({ type: Boolean }) preventsScroll = true;
12 |
13 | // eslint-disable-next-line class-methods-use-this
14 | _defineOverlayConfig() {
15 | return {
16 | placementMode: "global",
17 | viewportConfig: {
18 | placement: "right",
19 | },
20 | handleAccessibility: true,
21 | hasBackdrop: this.hasBackdrop,
22 | hidesOnEsc: this.hidesOnEsc,
23 | hidesOnOutsideClick: this.hidesOnOutsideClick,
24 | preventsScroll: this.preventsScroll,
25 | trapsKeyboardFocus: this.trapsKeyboardFocus,
26 | };
27 | }
28 |
29 | _setupOpenCloseListeners() {
30 | super._setupOpenCloseListeners();
31 | this.__toggle = () => {
32 | this.opened = !this.opened;
33 | };
34 |
35 | if (this._overlayInvokerNode) {
36 | this._overlayInvokerNode.addEventListener("click", this.__toggle);
37 | }
38 | }
39 |
40 | _teardownOpenCloseListeners() {
41 | super._teardownOpenCloseListeners();
42 |
43 | if (this._overlayInvokerNode) {
44 | this._overlayInvokerNode.removeEventListener("click", this.__toggle);
45 | }
46 | }
47 |
48 | render() {
49 | return html`
50 |
51 |
52 |
53 |
54 |
55 | `;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/packages/sheet/src/SheetContent.js:
--------------------------------------------------------------------------------
1 | import { LitElement, html, svg, css, property } from "lit-element";
2 |
3 | export class SheetContent extends LitElement {
4 | static get closeIcon() {
5 | return svg` `;
6 | }
7 |
8 | static get styles() {
9 | return [
10 | css`
11 | @keyframes sheet-slide {
12 | 10% {
13 | transform: translateX(90%);
14 | }
15 | 20% {
16 | transform: translateX(80%);
17 | }
18 | 30% {
19 | transform: translateX(70%);
20 | }
21 | 40% {
22 | transform: translateX(60%);
23 | }
24 | 50% {
25 | transform: translateX(50%);
26 | }
27 | 60% {
28 | transform: translateX(40%);
29 | }
30 | 70% {
31 | transform: translateX(30%);
32 | }
33 | 80% {
34 | transform: translateX(20%);
35 | }
36 | 90% {
37 | transform: translateX(10%);
38 | }
39 | 100% {
40 | transform: translateX(0);
41 | }
42 | }
43 |
44 | :host {
45 | height: 100%;
46 | background-color: #ffffff;
47 | transform: translateX(100%);
48 | -webkit-animation: sheet-slide 0.3s forwards;
49 | animation: sheet-slide 0.3s forwards;
50 | }
51 |
52 | .close-icon {
53 | display: flex;
54 | cursor: pointer;
55 | margin: 0;
56 | position: absolute;
57 | top: 14px;
58 | right: 14px;
59 | z-index: 10;
60 | }
61 | `,
62 | ];
63 | }
64 | @property({ type: Boolean, reflect: true }) dismissable = true;
65 | @property({ type: String, reflect: true }) width = "320px";
66 |
67 | close() {
68 | this.dispatchEvent(new Event("close-overlay", { bubbles: true }));
69 | }
70 |
71 | get defaultCloseIcon() {
72 | return html`
73 |
74 | ${SheetContent.closeIcon}
75 |
76 | `;
77 | }
78 |
79 | render() {
80 | return html`
81 |
86 | ${this.dismissable ? this.defaultCloseIcon : ""}
87 |
88 | `;
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/packages/skeleton/README.md:
--------------------------------------------------------------------------------
1 | # Chameleon Skeleton
2 |
3 | ```js script
4 | import { html } from "@open-wc/demoing-storybook";
5 | import { withKnobs, text, number } from "@open-wc/demoing-storybook";
6 | import "./chameleon-skeleton.js";
7 |
8 | export default {
9 | title: "Components|Data and Visualizations/Skeleton",
10 | component: "chameleon-skeleton",
11 | decorators: [withKnobs],
12 | options: { selectedPanel: "storybookjs/docs/panel" },
13 | };
14 | ```
15 |
16 | ## Properties
17 |
18 | | Property Name | Type(s) | Default Value | Description |
19 | | ------------- | ------- | ------------- | --------------------------------------------- |
20 | | `theme` | String | `"primary"` | The skeleton's theme ("primary", "secondary") |
21 | | `height` | String | `"100%"` | The skeleton's height |
22 | | `width` | String | `"100%"` | The skeleton's width |
23 | | `cHeight` | Number | `50` | The skeleton's circle height |
24 |
25 | ## Examples
26 |
27 | ### Default
28 |
29 | ```js preview-story
30 | export const Default = () => {
31 | const height = text("Height", "100%");
32 | const width = text("Width", "100%");
33 | const theme = text("Theme", "primary");
34 | const cHeight = number("Circle Height", 50);
35 |
36 | return theme === "primary"
37 | ? html`
38 |
39 |
40 | `
41 | : theme === "secondary"
42 | ? html`
43 | `
44 | : "";
45 | };
46 | ```
47 |
--------------------------------------------------------------------------------
/packages/skeleton/__tests__/chameleon-skeleton.test.js:
--------------------------------------------------------------------------------
1 | import { fixture, html, expect } from "@open-wc/testing";
2 | import "../chameleon-skeleton.js";
3 |
4 | describe("chameleon-skeleton", () => {
5 | it("renders", async () => {
6 | const el = await fixture(html` `);
7 | expect(Boolean(el.shadowRoot)).to.equal(true);
8 | });
9 | it("returns a radius half the size of the circle height if theme is secondary", async () => {
10 | const el = await fixture(html` `);
11 | el.theme = "secondary";
12 | el.cHeight = 50;
13 | expect(el.circleRadius).to.eql(25);
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/packages/skeleton/chameleon-skeleton.js:
--------------------------------------------------------------------------------
1 | import { ChameleonSkeleton } from "./lib/ChameleonSkeleton.js";
2 |
3 | customElements.define("chameleon-skeleton", ChameleonSkeleton);
4 |
--------------------------------------------------------------------------------
/packages/skeleton/index.js:
--------------------------------------------------------------------------------
1 | export { ChameleonSkeleton } from "./lib/ChameleonSkeleton.js";
2 | export { ChameleonSkeletonStyle } from "./lib/ChameleonSkeletonStyle.js";
3 |
--------------------------------------------------------------------------------
/packages/skeleton/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@chameleon-ds/skeleton",
3 | "version": "2.0.1",
4 | "description": "Chameleon skeleton",
5 | "author": "Maritz Motivation Solutions, Inc.",
6 | "license": "MIT",
7 | "homepage": "https://github.com/MaritzSTL/chameleon/tree/master/packages/skeleton#readme",
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/MaritzSTL/chameleon.git"
11 | },
12 | "main": "index.js",
13 | "module": "index.js",
14 | "files": [
15 | "chameleon-skeleton.js",
16 | "/lib/"
17 | ],
18 | "scripts": {
19 | "test": "echo \"Error: run tests from root\" && exit 1",
20 | "build": "babel src --out-dir lib --config-file ../../babel.config.json"
21 | },
22 | "bugs": {
23 | "url": "https://github.com/MaritzSTL/chameleon/issues"
24 | },
25 | "dependencies": {
26 | "lit-element": "^2.2.1"
27 | },
28 | "publishConfig": {
29 | "access": "public"
30 | },
31 | "gitHead": "0f8abecfe290971a220b969fc4d82fba4f6869ad"
32 | }
33 |
--------------------------------------------------------------------------------
/packages/skeleton/src/ChameleonSkeleton.js:
--------------------------------------------------------------------------------
1 | import { LitElement, html, property, svg } from "lit-element";
2 | import { ChameleonSkeletonStyle } from "./ChameleonSkeletonStyle.js";
3 |
4 | export class ChameleonSkeleton extends LitElement {
5 | /**
6 | * Properties
7 | */
8 | @property({ type: String, reflect: true })
9 | theme = "primary";
10 |
11 | @property({ type: String, reflect: true })
12 | height = "100%";
13 |
14 | @property({ type: String, reflect: true })
15 | width = "100%";
16 |
17 | @property({ type: Number, reflect: true })
18 | cHeight = 50;
19 |
20 | /**
21 | * Styles
22 | */
23 | static styles = [ChameleonSkeletonStyle];
24 |
25 | /**
26 | * Template
27 | */
28 | render() {
29 | //TODO: add linear gradient animation
30 | /*
31 |
32 |
33 |
34 |
35 |
36 | */
37 | return html`
38 |
39 | ${this.theme === "primary"
40 | ? svg`
41 |
50 | `
51 | : this.theme === "secondary"
52 | ? svg`
53 | `
54 | : ``}
55 |
56 | `;
57 | }
58 |
59 | get circleRadius() {
60 | return this.cHeight * 0.5;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/packages/skeleton/src/ChameleonSkeletonStyle.js:
--------------------------------------------------------------------------------
1 | import { css } from "lit-element";
2 |
3 | export const ChameleonSkeletonStyle = css`
4 | .rectangle {
5 | fill: var(--color-gray-lightest, #e1e3e4);
6 | }
7 |
8 | .circle {
9 | fill: var(--color-gray-lightest, #e1e3e4);
10 | }
11 | `;
12 |
--------------------------------------------------------------------------------
/packages/switch/README.md:
--------------------------------------------------------------------------------
1 | # Chameleon Switch
2 |
3 | ```js script
4 | import { html } from "@open-wc/demoing-storybook";
5 | import { withKnobs, text, boolean } from "@open-wc/demoing-storybook";
6 | import "./chameleon-switch.js";
7 |
8 | export default {
9 | title: "Components|Form Elements/Switch",
10 | component: "chameleon-switch",
11 | decorators: [withKnobs],
12 | options: { selectedPanel: "storybookjs/docs/panel" },
13 | };
14 | ```
15 |
16 | ## Properties
17 |
18 | | Property Name | Type(s) | Default Value | Description |
19 | | ------------- | ------- | ------------- | --------------------------------- |
20 | | `label` | String | `""` | The switch's label |
21 | | `checked` | Boolean | `false` | If the switch is checked |
22 | | `readonly` | Boolean | `false` | If the switch's value is readonly |
23 | | `value` | String | `""` | The switch's current value |
24 |
25 | ## Examples
26 |
27 | ### Default
28 |
29 | ```js preview-story
30 | export const Default = () => {
31 | const label = text("Label", "");
32 | const checked = boolean("Checked", true);
33 | const readonly = boolean("Read Only", false);
34 |
35 | return html`
36 |
41 | `;
42 | };
43 | ```
44 |
--------------------------------------------------------------------------------
/packages/switch/__tests__/chameleon-switch.test.js:
--------------------------------------------------------------------------------
1 | import { litFixture, html, expect } from "@open-wc/testing";
2 | import "../chameleon-switch.js";
3 |
4 | const fixture = html` `;
5 |
6 | describe("chameleon-switch", () => {
7 | let element;
8 |
9 | it("renders", async () => {
10 | element = await litFixture(fixture);
11 | expect(Boolean(element.shadowRoot)).to.equal(true);
12 | });
13 |
14 | it("renders labelText", () => {
15 | element.label = "chameleon";
16 |
17 | expect(element.labelText).to.equal("chameleon");
18 | });
19 | });
20 |
--------------------------------------------------------------------------------
/packages/switch/chameleon-switch.js:
--------------------------------------------------------------------------------
1 | import { ChameleonSwitch } from "./lib/ChameleonSwitch.js";
2 |
3 | customElements.define("chameleon-switch", ChameleonSwitch);
4 |
--------------------------------------------------------------------------------
/packages/switch/index.js:
--------------------------------------------------------------------------------
1 | export { ChameleonSwitch } from "./lib/ChameleonSwitch.js";
2 | export { ChameleonSwitchStyle } from "./lib/ChameleonSwitchStyle.js";
3 |
--------------------------------------------------------------------------------
/packages/switch/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@chameleon-ds/switch",
3 | "version": "2.0.1",
4 | "description": "Chameleon switch",
5 | "author": "Maritz Motivation Solutions, Inc.",
6 | "license": "MIT",
7 | "homepage": "https://github.com/MaritzSTL/chameleon/tree/master/packages/switch#readme",
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/MaritzSTL/chameleon.git"
11 | },
12 | "main": "index.js",
13 | "module": "index.js",
14 | "files": [
15 | "chameleon-switch.js",
16 | "/lib/"
17 | ],
18 | "scripts": {
19 | "test": "echo \"Error: run tests from root\" && exit 1",
20 | "build": "babel src --out-dir lib --config-file ../../babel.config.json"
21 | },
22 | "bugs": {
23 | "url": "https://github.com/MaritzSTL/chameleon/issues"
24 | },
25 | "dependencies": {
26 | "lit-element": "^2.2.1"
27 | },
28 | "publishConfig": {
29 | "access": "public"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/packages/switch/src/ChameleonSwitch.js:
--------------------------------------------------------------------------------
1 | import { LitElement, html, property } from "lit-element";
2 | import { nothing } from "lit-html";
3 | import { ChameleonSwitchStyle } from "./ChameleonSwitchStyle.js";
4 |
5 | export class ChameleonSwitch extends LitElement {
6 | /**
7 | * Properties
8 | */
9 |
10 | // The switch's label
11 | @property({ type: String })
12 | label = "";
13 |
14 | // A Boolean which, if true, indicates that the switch is selected
15 | @property({ type: Boolean, reflect: true })
16 | checked = false;
17 |
18 | // A Boolean attribute which, if true, indicates that the switch cannot be edited
19 | @property({ type: Boolean, reflect: true })
20 | readonly = false;
21 |
22 | // The switch's current value
23 | @property({ type: String })
24 | value = "";
25 |
26 | /**
27 | * Styles
28 | */
29 | static styles = [ChameleonSwitchStyle];
30 |
31 | /**
32 | * Template
33 | */
34 | render() {
35 | return html`
36 |
37 |
38 |
39 |
40 | ${this.labelText}
41 | `;
42 | }
43 |
44 | get labelText() {
45 | if (this.label !== "") return this.label;
46 | else return nothing;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/packages/switch/src/ChameleonSwitchStyle.js:
--------------------------------------------------------------------------------
1 | import { css } from "lit-element";
2 |
3 | export const ChameleonSwitchStyle = css`
4 | :host {
5 | align-items: center;
6 | display: inline-flex;
7 | font-size: var(--font-size-input, 0.938rem);
8 | }
9 |
10 | :host([readonly]) {
11 | pointer-events: none;
12 | }
13 |
14 | .switch {
15 | display: inline-block;
16 | height: 20px;
17 | margin-right: 10px;
18 | position: relative;
19 | width: 32px;
20 | }
21 |
22 | .switch input {
23 | display: none;
24 | }
25 |
26 | .slider {
27 | background-color: var(--color-gray-lightest, #e1e3e4);
28 | border-radius: 10px;
29 | bottom: 0;
30 | cursor: pointer;
31 | left: 0;
32 | position: absolute;
33 | right: 0;
34 | top: 0;
35 | transition: 0.4s;
36 | }
37 |
38 | .slider:before {
39 | background-color: var(--color-surface, #ffffff);
40 | border-radius: 50%;
41 | bottom: 2px;
42 | box-shadow: 1px 0 3px var(--color-box-shadow, rgba(159, 164, 168, 0.6));
43 | content: "";
44 | height: 16px;
45 | left: 2px;
46 | position: absolute;
47 | transition: 0.4s;
48 | width: 16px;
49 | }
50 |
51 | input:checked + .slider {
52 | background-color: var(--color-primary, #2c6fb7);
53 | }
54 |
55 | input:focus + .slider {
56 | box-shadow: 0 0 3px var(--color-gray-dark, #9fa4a8);
57 | }
58 |
59 | input:checked + .slider:before {
60 | box-shadow: none;
61 | transform: translateX(12px);
62 | }
63 | `;
64 |
--------------------------------------------------------------------------------
/packages/table/chameleon-table.js:
--------------------------------------------------------------------------------
1 | import { ChameleonTable } from "./lib/ChameleonTable.js";
2 |
3 | customElements.define("chameleon-table", ChameleonTable);
4 |
--------------------------------------------------------------------------------
/packages/table/index.js:
--------------------------------------------------------------------------------
1 | export { ChameleonTable } from "./lib/ChameleonTable.js";
2 | export { ChameleonTableStyle } from "./lib/ChameleonTableStyle.js";
3 |
--------------------------------------------------------------------------------
/packages/table/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@chameleon-ds/table",
3 | "version": "2.0.1",
4 | "description": "Chameleon Table",
5 | "author": "Maritz Motivation Solutions, Inc.",
6 | "license": "MIT",
7 | "homepage": "https://github.com/MaritzSTL/chameleon/tree/master/packages/tables#readme",
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/MaritzSTL/chameleon.git"
11 | },
12 | "main": "index.js",
13 | "module": "index.js",
14 | "files": [
15 | "chameleon-table.js",
16 | "/lib/"
17 | ],
18 | "scripts": {
19 | "test": "echo \"Error: run tests from root\" && exit 1",
20 | "build": "babel src --out-dir lib --config-file ../../babel.config.json"
21 | },
22 | "bugs": {
23 | "url": "https://github.com/MaritzSTL/chameleon/issues"
24 | },
25 | "dependencies": {
26 | "@chameleon-ds/input": "^2.0.1",
27 | "@chameleon-ds/multiselect": "^2.0.1",
28 | "@chameleon-ds/paginator": "^2.0.1",
29 | "lit-element": "^2.2.1"
30 | },
31 | "publishConfig": {
32 | "access": "public"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/packages/tabs/README.md:
--------------------------------------------------------------------------------
1 | # Chameleon Tabs
2 |
3 | ```js script
4 | import { html } from "@open-wc/demoing-storybook";
5 | import "./chameleon-tab.js";
6 | import "./chameleon-tabs.js";
7 |
8 | export default {
9 | title: "Components|Navigation/Tabs",
10 | component: "chameleon-tabs",
11 | options: { selectedPanel: "storybookjs/docs/panel" },
12 | };
13 | ```
14 |
15 | ## Properties
16 |
17 | ### chameleon-tabs
18 |
19 | | Property Name | Type(s) | Default Value | Description |
20 | | ------------- | ------- | ------------- | -------------------------------------------------------------- |
21 | | `urlRewrite` | Boolean | `true` | Automatically rewrite URL with tab index information when true |
22 | | `selected` | Number | `0` | The selected tab's index |
23 |
24 | ## Examples
25 |
26 | ### Default
27 |
28 | ```js preview-story
29 | export const Default = () => html`
30 |
31 |
32 | Tab One
33 |
34 |
35 | Tab Two
36 |
37 |
38 | Tab Three
39 |
40 |
41 | `;
42 | ```
43 |
--------------------------------------------------------------------------------
/packages/tabs/__tests__/chameleon-tabs.test.js:
--------------------------------------------------------------------------------
1 | import { litFixture, html, expect } from "@open-wc/testing";
2 | import sinon from "sinon";
3 | import { ChameleonTabs } from "../index.js";
4 | import "../chameleon-tab.js";
5 | import "../chameleon-tabs.js";
6 |
7 | const fixture = html`
8 |
9 | `;
10 |
11 | describe("chameleon-tabs", () => {
12 | let element;
13 |
14 | beforeEach(async () => {
15 | element = await litFixture(fixture);
16 | });
17 |
18 | it("renders", async () => {
19 | expect(Boolean(element.shadowRoot)).to.equal(true);
20 | });
21 |
22 | it("dispatches an event on handleToggle", () => {
23 | const tab = element.querySelector("chameleon-tab");
24 | const spy = sinon.spy(tab, "dispatchEvent");
25 |
26 | tab.handleToggle();
27 |
28 | expect(spy).to.be.calledOnce;
29 | });
30 |
31 | it("throws error if no tabs are given", () => {
32 | expect(() => new ChameleonTabs().firstUpdated()).to.throw();
33 | });
34 |
35 | it("updates selected tab", async () => {
36 | element.selected = 0;
37 | element.requestUpdate();
38 | await element.updateComplete;
39 |
40 | expect(element.selected).to.equal(0);
41 | });
42 |
43 | it("sets active attribute to true", async () => {
44 | element = await litFixture(
45 | html`
46 |
47 |
48 |
49 |
50 | `
51 | );
52 | element.selected = 0;
53 | element.requestUpdate();
54 | await element.updateComplete;
55 |
56 | expect(element.selected).to.equal(0);
57 |
58 | element.selected = 1;
59 | element.requestUpdate();
60 | await element.updateComplete;
61 |
62 | expect(element.selected).to.equal(1);
63 | });
64 | });
65 |
--------------------------------------------------------------------------------
/packages/tabs/chameleon-tab.js:
--------------------------------------------------------------------------------
1 | import { ChameleonTab } from "./lib/ChameleonTab.js";
2 |
3 | customElements.define("chameleon-tab", ChameleonTab);
4 |
--------------------------------------------------------------------------------
/packages/tabs/chameleon-tabs.js:
--------------------------------------------------------------------------------
1 | import { ChameleonTabs } from "./lib/ChameleonTabs.js";
2 |
3 | customElements.define("chameleon-tabs", ChameleonTabs);
4 |
--------------------------------------------------------------------------------
/packages/tabs/index.js:
--------------------------------------------------------------------------------
1 | export { ChameleonTab } from "./lib/ChameleonTab.js";
2 | export { ChameleonTabs } from "./lib/ChameleonTabs.js";
3 | export { ChameleonTabsStyle } from "./lib/ChameleonTabsStyle.js";
4 |
--------------------------------------------------------------------------------
/packages/tabs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@chameleon-ds/tabs",
3 | "version": "2.0.1",
4 | "description": "Chameleon tabs",
5 | "author": "Maritz Motivation Solutions, Inc.",
6 | "license": "MIT",
7 | "homepage": "https://github.com/MaritzSTL/chameleon/tree/master/packages/tabs#readme",
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/MaritzSTL/chameleon.git"
11 | },
12 | "main": "index.js",
13 | "module": "index.js",
14 | "files": [
15 | "chameleon-tab.js",
16 | "chameleon-tabs.js",
17 | "/lib/"
18 | ],
19 | "scripts": {
20 | "test": "echo \"Error: run tests from root\" && exit 1",
21 | "build": "babel src --out-dir lib --config-file ../../babel.config.json"
22 | },
23 | "bugs": {
24 | "url": "https://github.com/MaritzSTL/chameleon/issues"
25 | },
26 | "dependencies": {
27 | "lit-element": "^2.2.1"
28 | },
29 | "publishConfig": {
30 | "access": "public"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/packages/tabs/src/ChameleonTab.js:
--------------------------------------------------------------------------------
1 | import { LitElement, html } from "lit-element";
2 |
3 | export class ChameleonTab extends LitElement {
4 | constructor() {
5 | super();
6 |
7 | this.addEventListener("click", this.handleToggle);
8 | }
9 |
10 | /**
11 | * Template
12 | */
13 | render() {
14 | return html` `;
15 | }
16 |
17 | handleToggle() {
18 | this.dispatchEvent(
19 | new CustomEvent("chameleon.tabs.selected-changed", {
20 | detail: {
21 | value: this.dataset.index,
22 | },
23 | bubbles: true,
24 | composed: true,
25 | })
26 | );
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/packages/tabs/src/ChameleonTabs.js:
--------------------------------------------------------------------------------
1 | import { LitElement, property, html } from "lit-element";
2 | import { ChameleonTabsStyle } from "./ChameleonTabsStyle.js";
3 |
4 | export class ChameleonTabs extends LitElement {
5 | constructor() {
6 | super();
7 | this.addEventListener(
8 | "chameleon.tabs.selected-changed",
9 | this._handleSelectedChanged
10 | );
11 | }
12 |
13 | /**
14 | * Lifecycle Methods
15 | */
16 | firstUpdated() {
17 | // Index tabs
18 | const tabs = Array.from(this.querySelectorAll("chameleon-tab"));
19 | if (tabs.length <= 0)
20 | throw new Error(
21 | " must have at least one element"
22 | );
23 | tabs.forEach((tab, i) => tab.setAttribute("data-index", i.toString()));
24 |
25 | // If has an id, allow the selected tab index to
26 | // be set using query params: ?tabs_=1
27 | if (this.id) {
28 | const params = new URLSearchParams(window.location.search);
29 | if (params.has(`tabs_${this.id}`)) {
30 | const index = parseInt(params.get(`tabs_${this.id}`));
31 | this.selected = index <= tabs.length - 1 ? index : 0;
32 | } else {
33 | if (this.urlRewrite)
34 | params.append(`tabs_${this.id}`, String(this.selected));
35 | }
36 | }
37 | }
38 |
39 | updated(changedProperties) {
40 | if (changedProperties.has("selected")) {
41 | const tabs = Array.from(this.querySelectorAll("chameleon-tab"));
42 |
43 | tabs.forEach((tab, i) => {
44 | tab.removeAttribute("active");
45 | if (i === this.selected) tab.setAttribute("active", "true");
46 | });
47 | }
48 | }
49 |
50 | /**
51 | * Properties
52 | */
53 | @property({ type: Number, reflect: true })
54 | selected = 0;
55 |
56 | /** Automatically rewrite URL with tab index information. Default: true. */
57 | @property({ type: Boolean })
58 | urlRewrite = true;
59 |
60 | /**
61 | * Styles
62 | */
63 | static styles = [ChameleonTabsStyle];
64 |
65 | /**
66 | * Template
67 | */
68 | render() {
69 | return html` `;
70 | }
71 |
72 | _handleSelectedChanged(e) {
73 | e.preventDefault();
74 | this.selected = parseInt(e.detail.value);
75 | this.updateQueryParams();
76 | }
77 |
78 | updateQueryParams() {
79 | const params = new URLSearchParams(window.location.search);
80 | if (this.urlRewrite) params.set(`tabs_${this.id}`, String(this.selected));
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/packages/tabs/src/ChameleonTabsStyle.js:
--------------------------------------------------------------------------------
1 | import { css } from "lit-element";
2 |
3 | export const ChameleonTabsStyle = css`
4 | :host {
5 | box-shadow: inset 0 -1px 0 0 rgba(26, 57, 96, 0.1);
6 | display: flex;
7 | justify-content: space-around;
8 | }
9 |
10 | ::slotted(chameleon-tab) {
11 | align-items: center;
12 | box-sizing: border-box;
13 | display: flex;
14 | flex-grow: 1;
15 | font-size: 1.125em;
16 | height: 65px;
17 | justify-content: center;
18 | padding: 8px 12px;
19 | color: var(--color-gray-light, #c4c7ca);
20 | }
21 |
22 | ::slotted(chameleon-tab:hover) {
23 | cursor: pointer;
24 | color: var(--color-secondary, #69c9b9);
25 | }
26 |
27 | ::slotted([active]) {
28 | border-bottom: solid 1px var(--color-secondary, #69c9b9);
29 | box-shadow: inset 0 -2px 0 0 var(--color-secondary, #69c9b9);
30 | color: var(--color-secondary, #69c9b9);
31 | }
32 | `;
33 |
--------------------------------------------------------------------------------
/packages/textarea/__tests__/chameleon-textarea.test.js:
--------------------------------------------------------------------------------
1 | import "../chameleon-textarea.js";
2 | import { litFixture, html, expect } from "@open-wc/testing";
3 | import sinon from "sinon";
4 |
5 | const fixture = html` `;
6 |
7 | describe("chameleon-textarea", () => {
8 | let element;
9 |
10 | beforeEach(async () => {
11 | element = await litFixture(fixture);
12 | });
13 |
14 | it("renders", () => {
15 | expect(Boolean(element.shadowRoot)).to.equal(true);
16 | });
17 |
18 | it("returns _el", () => {
19 | const el = element._el;
20 | expect(el.constructor.name).to.equal("HTMLTextAreaElement");
21 | });
22 |
23 | it("_el returns null if shadowRoot is null", () => {
24 | sinon.stub(element, "shadowRoot").get(() => null);
25 |
26 | expect(element._el).to.be.null;
27 | });
28 |
29 | it("renders labelText", () => {
30 | element.label = "chameleon";
31 | expect(element.labelText.constructor.name).to.equal("TemplateResult");
32 | });
33 |
34 | it("renders errorText", () => {
35 | element.validationMessage = "chameleon";
36 | expect(element.errorText.constructor.name).to.equal("TemplateResult");
37 | });
38 |
39 | it("returns validity", () => {
40 | expect(element.validity.constructor.name).to.equal("ValidityState");
41 | });
42 |
43 | it("validity returns undefined if _el is null", () => {
44 | sinon.stub(element, "_el").get(() => null);
45 |
46 | expect(element.validity).to.be.undefined;
47 | });
48 |
49 | it("willValidate returns a boolean", () => {
50 | expect(typeof element.willValidate).to.equal("boolean");
51 | });
52 |
53 | it("willValidate returns false if _el is null", () => {
54 | sinon.stub(element, "_el").get(() => null);
55 |
56 | expect(element.willValidate).to.be.false;
57 | });
58 |
59 | it("checkValidity returns a boolean", () => {
60 | expect(typeof element.checkValidity()).to.equal("boolean");
61 | });
62 |
63 | it("checkValidity returns false if _el is null", () => {
64 | sinon.stub(element, "_el").get(() => null);
65 |
66 | expect(element.checkValidity()).to.be.false;
67 | });
68 |
69 | it("invalid sets aria-invalid attribute", async () => {
70 | element.value = "";
71 | element.invalid = true;
72 | await element.updateComplete;
73 | expect(element._el).to.have.attribute("aria-invalid");
74 | });
75 |
76 | it("_handleBlur calls checkValidity", () => {
77 | // TBH I'm not convinced this test is actually behaving expectedly...
78 | const checkValidity = sinon.spy(element, "checkValidity");
79 | const handleBlur = sinon.spy(element, "_handleBlur");
80 |
81 | element._handleBlur();
82 |
83 | expect(checkValidity.calledImmediatelyAfter(handleBlur));
84 | });
85 |
86 | it("_handleInvalid sets validationMessage", () => {
87 | element._handleInvalid();
88 | expect(element.validationMessage).to.equal(element._el.validationMessage);
89 | });
90 |
91 | it("_handleInvalid returns an empty string if _el is null", () => {
92 | sinon.stub(element, "_el").get(() => null);
93 | element._handleInvalid();
94 |
95 | expect(element.validationMessage).to.equal("");
96 | });
97 |
98 | it("handles input", () => {
99 | element._handleInput({ target: { value: "chameleon" } });
100 | expect(element.value).to.equal("chameleon");
101 | });
102 | });
103 |
--------------------------------------------------------------------------------
/packages/textarea/chameleon-textarea.js:
--------------------------------------------------------------------------------
1 | import { ChameleonTextarea } from "./lib/ChameleonTextarea.js";
2 |
3 | customElements.define("chameleon-textarea", ChameleonTextarea);
4 |
--------------------------------------------------------------------------------
/packages/textarea/index.js:
--------------------------------------------------------------------------------
1 | export { ChameleonTextarea } from "./lib/ChameleonTextarea.js";
2 | export { ChameleonTextareaStyle } from "./lib/ChameleonTextareaStyle.js";
3 |
--------------------------------------------------------------------------------
/packages/textarea/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@chameleon-ds/textarea",
3 | "version": "2.0.1",
4 | "description": "Chameleon textarea",
5 | "author": "Maritz Motivation Solutions, Inc.",
6 | "license": "MIT",
7 | "homepage": "https://github.com/MaritzSTL/chameleon/tree/master/packages/textarea#readme",
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/MaritzSTL/chameleon.git"
11 | },
12 | "main": "index.js",
13 | "module": "index.js",
14 | "files": [
15 | "chameleon-textarea.js",
16 | "/lib/"
17 | ],
18 | "scripts": {
19 | "test": "echo \"Error: run tests from root\" && exit 1",
20 | "build": "babel src --out-dir lib --config-file ../../babel.config.json"
21 | },
22 | "bugs": {
23 | "url": "https://github.com/MaritzSTL/chameleon/issues"
24 | },
25 | "dependencies": {
26 | "lit-element": "^2.2.1"
27 | },
28 | "publishConfig": {
29 | "access": "public"
30 | },
31 | "gitHead": "0f8abecfe290971a220b969fc4d82fba4f6869ad"
32 | }
33 |
--------------------------------------------------------------------------------
/packages/textarea/src/ChameleonTextareaStyle.js:
--------------------------------------------------------------------------------
1 | import { css } from "lit-element";
2 |
3 | export const ChameleonTextareaStyle = css`
4 | :host {
5 | display: inline-flex;
6 | flex-direction: column;
7 | font-family: var(--font-family, sans-serif);
8 | }
9 |
10 | textarea {
11 | border: 1px solid var(--color-gray-light, #c4c7ca);
12 | border-radius: var(--border-radius-input, 0.313rem);
13 | font-family: inherit;
14 | font-size: var(--font-size-input, 0.938rem);
15 | padding: var(--textarea-padding, 0.438rem 0.813rem);
16 | }
17 |
18 | textarea[nonresizeable] {
19 | resize: none;
20 | }
21 |
22 | label {
23 | color: var(--color-gray-darkest, #6c737a);
24 | font-size: var(--font-size-label, 0.875rem);
25 | margin-bottom: 10px;
26 | }
27 |
28 | .error {
29 | color: var(--color-error, #bc1c16);
30 | font-size: var(--font-size-label, 0.875rem);
31 | margin-top: 3px;
32 | }
33 | :host([invalid]) textarea,
34 | textarea.invalid {
35 | border-color: var(--color-error, #bc1c16);
36 | }
37 | `;
38 |
--------------------------------------------------------------------------------
/packages/theme/README.md:
--------------------------------------------------------------------------------
1 | # Global Theme Variables
2 |
3 | ```js script
4 | export default {
5 | title: "Theming|Global",
6 | };
7 | ```
8 |
9 | ```css
10 | :host {
11 | --border-radius: 0.5rem;
12 | --border-radius-input: 0.313rem;
13 | --button-padding: 0.75rem 1.375rem;
14 | --input-padding: 0.625rem 0.5rem;
15 | --textarea-padding: 0.438rem 0.813rem;
16 | --select-padding: 0.438rem 0.5rem;
17 | --dialog-width: 18.75rem;
18 |
19 | --color-surface: #ffffff;
20 | --color-black: #252a33;
21 | --color-background: #f5f5f8;
22 | --color-primary: #2c6fb7;
23 | --color-primary-light: #679dea;
24 | --color-primary-dark: #004587;
25 | --color-secondary: #69c9b9;
26 | --color-secondary-light: #9cfceb;
27 | --color-secondary-dark: #349889;
28 | --color-gray-lightest: #e1e3e4;
29 | --color-gray-light: #c4c7ca;
30 | --color-gray-dark: #9fa4a8;
31 | --color-gray-darkest: #6c737a;
32 | --color-warning: #fcb61a;
33 | --color-warning-light: #fdd375;
34 | --color-warning-lightest: #fef0d1;
35 | --color-error: #bc1c16;
36 | --color-error-light: #fdd375;
37 | --color-error-lightest: #fef0d1;
38 | --color-success: #00870a;
39 | --color-success-light: #fdd375;
40 | --color-success-lightest: #fef0d1;
41 | --color-box-shadow: rgba(159, 164, 168, 0.6);
42 |
43 | --font-letter-spacing: 0.018rem;
44 | --font-size-paragraph-medium: 0.938rem;
45 | --font-size-subtitle: 0.938rem;
46 | --font-size-title: 1.4rem;
47 | --font-size-input: 0.938rem;
48 | --font-size-label: 0.875rem;
49 | --font-family: sans-serif;
50 | --font-size-table-header: 1rem;
51 | --font-size-table-content: 0.875rem;
52 | }
53 | ```
54 |
--------------------------------------------------------------------------------
/packages/theme/base/index.js:
--------------------------------------------------------------------------------
1 | import { css } from "lit-element";
2 |
3 | export default css`
4 | :host {
5 | --border-radius: 0.5rem;
6 | --border-radius-input: 0.313rem;
7 | --button-padding: 0.75rem 1.375rem;
8 | --input-padding: 0.625rem 0.5rem;
9 | --textarea-padding: 0.438rem 0.813rem;
10 | --select-padding: 0.438rem 0.5rem;
11 | --dialog-width: 18.75rem;
12 |
13 | --color-surface: #ffffff;
14 | --color-black: #252a33;
15 | --color-background: #f5f5f8;
16 | --color-primary: #2c6fb7;
17 | --color-primary-light: #679dea;
18 | --color-primary-dark: #004587;
19 | --color-secondary: #69c9b9;
20 | --color-secondary-light: #9cfceb;
21 | --color-secondary-dark: #349889;
22 | --color-gray-lightest: #e1e3e4;
23 | --color-gray-light: #c4c7ca;
24 | --color-gray-dark: #9fa4a8;
25 | --color-gray-darkest: #6c737a;
26 | --color-warning: #fcb61a;
27 | --color-warning-light: #fdd375;
28 | --color-warning-lightest: #fef0d1;
29 | --color-error: #bc1c16;
30 | --color-error-light: #fdd375;
31 | --color-error-lightest: #fef0d1;
32 | --color-success: #00870a;
33 | --color-success-light: #fdd375;
34 | --color-success-lightest: #fef0d1;
35 | --color-box-shadow: rgba(159, 164, 168, 0.6);
36 |
37 | --font-letter-spacing: 0.018rem;
38 | --font-size-paragraph-medium: 0.938rem;
39 | --font-size-subtitle: 0.938rem;
40 | --font-size-title: 1.4rem;
41 | --font-size-input: 0.938rem;
42 | --font-size-label: 0.875rem;
43 | --font-family: sans-serif;
44 | --font-size-table-header: 1rem;
45 | --font-size-table-content: 0.875rem;
46 | }
47 | `;
48 |
--------------------------------------------------------------------------------
/packages/theme/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@chameleon-ds/theme",
3 | "version": "2.0.1",
4 | "description": "Chameleon design language",
5 | "author": "Maritz Motivation Solutions, Inc.",
6 | "license": "MIT",
7 | "homepage": "https://github.com/MaritzSTL/chameleon/tree/master/packages/core#readme",
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/MaritzSTL/chameleon.git"
11 | },
12 | "main": "index.js",
13 | "module": "index.js",
14 | "files": [
15 | "/lib/"
16 | ],
17 | "scripts": {
18 | "test": "echo \"Error: run tests from root\" && exit 1",
19 | "build": "babel base --out-dir lib --config-file ../../babel.config.json"
20 | },
21 | "bugs": {
22 | "url": "https://github.com/MaritzSTL/chameleon/issues"
23 | },
24 | "dependencies": {
25 | "lit-element": "^2.2.1"
26 | },
27 | "publishConfig": {
28 | "access": "public"
29 | },
30 | "gitHead": "903c637e2d1f3693b6c0b5fca5c1e6363ecb15c1"
31 | }
32 |
--------------------------------------------------------------------------------
/packages/timezone/README.md:
--------------------------------------------------------------------------------
1 | # Chameleon Timezone
2 |
3 | ```js script
4 | import { html } from "@open-wc/demoing-storybook";
5 | import { withKnobs, text, boolean } from "@open-wc/demoing-storybook";
6 | import "./chameleon-timezone.js";
7 |
8 | export default {
9 | title: "Components|Form Elements/Timezone",
10 | component: "chameleon-timezone",
11 | decorators: [withKnobs],
12 | options: { selectedPanel: "storybookjs/docs/panel" },
13 | };
14 | ```
15 |
16 | ## Properties
17 |
18 | | Property Name | Type(s) | Default Value | Description |
19 | | ------------------ | ------- | ---------------- | -------------------------------------------------------------------------------------------------------- |
20 | | `required` | Boolean | `false` | A Boolean which, if true, indicates that the timezone must have a value before the form can be submitted |
21 | | `invalid` | Boolean | `false` | Invalid boolean to allow validity access from higher level form errors |
22 | | `readonly` | Boolean | `false` | A Boolean attribute which, if true, indicates that the timezone cannot be edited |
23 | | `disabled` | Boolean | `false` | A Boolean attribute which is present if the timezone should be disabled |
24 | | `name` | String | `"cha-timezone"` | The timezone's form name |
25 | | `timezoneLabel` | String | `""` | The timezone's label |
26 | | `timezoneSubLabel` | String | `""` | The timezone's sub label |
27 | | `errors` | Array | `[]` | The skeleton's circle height |
28 |
29 | ## Examples
30 |
31 | ### Default
32 |
33 | ```js preview-story
34 | export const Default = () => {
35 | const timezoneLabel = text("Label", "Please select your Timezone");
36 | const timezoneSubLabel = text("Sub Label", "");
37 | const readonly = boolean("Read Only", false);
38 | const invalid = boolean("Invalid", false);
39 | const required = boolean("Required", false);
40 | const disabled = boolean("Disabled", false);
41 |
42 | return html`
43 |
51 | `;
52 | };
53 | ```
54 |
55 | ### Error State
56 |
57 | ```js preview-story
58 | export const ErrorState = () => html`
59 |
64 | `;
65 | ```
66 |
--------------------------------------------------------------------------------
/packages/timezone/__tests__/chameleon-timezone.test.js:
--------------------------------------------------------------------------------
1 | import { ChameleonTimezone, ChameleonTimezoneStyle } from "../index.js";
2 | import "../chameleon-timezone.js";
3 |
4 | /**
5 | * TODO(ryuhhnn): 4/3/2020 - Commented these all out because it's causing a test
6 | * failure and don't have time to look into it right now
7 | */
8 | // import { html, fixture, expect } from "@open-wc/testing";
9 |
10 | // describe("chameleon-timezone", () => {
11 | // const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
12 | // let element;
13 |
14 | // beforeEach(async () => {
15 | // element = await fixture(
16 | // html` `
17 | // );
18 | // });
19 |
20 | // it("should have tag name defined", () => {
21 | // expect(element.tagName.toLowerCase()).to.equal("chameleon-timezone");
22 | // });
23 |
24 | // describe("timezone()", () => {
25 | // it("should set timezone", () => {
26 | // element.timezone = timezone;
27 | // expect(element.timezone).to.equal(element._timezoneValue);
28 | // });
29 |
30 | // it("should get timezone", () => {
31 | // expect(element.timezone).to.equal(element._timezoneValue);
32 | // });
33 |
34 | // // TODO
35 | // xit("should default to local timezone if none is supplied", () => {
36 | // expect(element.timezone).to.equal(element.localTimeone);
37 | // });
38 | // });
39 |
40 | // describe("render()", () => {
41 | // it("should render shadowDom", () => {
42 | // expect(element).shadowDom.to.equalSnapshot();
43 | // });
44 |
45 | // it("should render lightDom", () => {
46 | // expect(element).lightDom.to.equal(``);
47 | // });
48 |
49 | // /**
50 | // * Labels
51 | // */
52 |
53 | // it("should render timezoneLabel", async () => {
54 | // element = await fixture(
55 | // html` `
56 | // );
57 | // expect(element).shadowDom.to.equalSnapshot();
58 | // });
59 |
60 | // it("should render timeoneSubLabel", async () => {
61 | // element = await fixture(
62 | // html`
63 | //
64 | // `
65 | // );
66 | // expect(element).shadowDom.to.equalSnapshot();
67 | // });
68 |
69 | // it("should render errors", async () => {
70 | // element.errors = ["asdf"];
71 | // expect(
72 | // element.shadowRoot.querySelector(".mdc-text-field-error-text")
73 | // ).to.not.equal(undefined);
74 | // });
75 | // });
76 |
77 | // describe("localTimezone()", () => {
78 | // it("should return the users's local timeZone", () => {
79 | // expect(element.timezone).to.equal(
80 | // Intl.DateTimeFormat().resolvedOptions().timeZone
81 | // );
82 | // });
83 | // });
84 |
85 | // describe("handleInput()", () => {
86 | // it("should update timezone value", () => {
87 | // element.value = "US/Pacific";
88 | // expect(element._timezoneValue).to.equal("US/Pacific");
89 | // });
90 | // });
91 | // });
92 |
--------------------------------------------------------------------------------
/packages/timezone/chameleon-timezone.js:
--------------------------------------------------------------------------------
1 | import { ChameleonTimezone } from "./lib/ChameleonTimezone.js";
2 |
3 | customElements.define("chameleon-timezone", ChameleonTimezone);
4 |
--------------------------------------------------------------------------------
/packages/timezone/index.js:
--------------------------------------------------------------------------------
1 | export { ChameleonTimezone } from "./lib/ChameleonTimezone.js";
2 | export { ChameleonTimezoneStyle } from "./lib/ChameleonTimezoneStyle.js";
3 |
--------------------------------------------------------------------------------
/packages/timezone/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@chameleon-ds/timezone",
3 | "version": "2.0.1",
4 | "description": "Chameleon timezone",
5 | "author": "Maritz Motivation Solutions, Inc.",
6 | "license": "MIT",
7 | "homepage": "https://github.com/MaritzSTL/chameleon/tree/master/packages/timezone#readme",
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/MaritzSTL/chameleon.git"
11 | },
12 | "main": "index.js",
13 | "module": "index.js",
14 | "files": [
15 | "chameleon-timezone.js",
16 | "/lib/",
17 | "/data/"
18 | ],
19 | "scripts": {
20 | "test": "echo \"Error: run tests from root\" && exit 1",
21 | "build": "babel src --out-dir lib --config-file ../../babel.config.json"
22 | },
23 | "bugs": {
24 | "url": "https://github.com/MaritzSTL/chameleon/issues"
25 | },
26 | "dependencies": {
27 | "@chameleon-ds/select": "^2.0.1",
28 | "lit-element": "^2.2.1"
29 | },
30 | "publishConfig": {
31 | "access": "public"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/packages/timezone/src/ChameleonTimezoneStyle.js:
--------------------------------------------------------------------------------
1 | import { css } from "lit-element";
2 |
3 | export const ChameleonTimezoneStyle = css`
4 | :host([readonly]),
5 | :host([disabled]) {
6 | pointer-events: none;
7 | }
8 |
9 | :host([disabled]) * {
10 | background-color: #f5f5f8;
11 | }
12 |
13 | input {
14 | border: 1px solid #e8e8e8);
15 | border-radius: var(--border-radius-input, 5px);
16 | font-family: inherit;
17 | font-size: 16px;
18 | padding: var(--select-padding, 0.438rem 0.5rem);
19 | }
20 |
21 | .mdc-text-field-error-text {
22 | color: var(--color-error-light, #fef0d1);
23 | }
24 |
25 | .label {
26 | color: var(--color-gray-darkest, #6c737a);
27 | font-family: var(--font-family, sans-serif);
28 | font-size: var(--font-size-label, 0.875rem);
29 | display: grid;
30 | font-weight: 500;
31 | font-size: 14px;
32 | margin: 7px 0;
33 | }
34 |
35 | .datetime-inputs.invalid .label{
36 | color: var(--color-error, #bc1c16);
37 | }
38 |
39 | @media screen and (max-width: 768px) {
40 | .inputSpacing {
41 | grid-template-columns: 1fr 1fr;
42 | grid-template-rows: 1fr 1fr;
43 | }
44 | }
45 |
46 | @media screen and (max-width: 375px) {
47 | .inputSpacing {
48 | grid-template-columns: 1fr;
49 | grid-template-rows: 1fr;
50 | }
51 | }
52 | `;
53 |
--------------------------------------------------------------------------------
/packages/toast/README.md:
--------------------------------------------------------------------------------
1 | # Chameleon Toast
2 |
3 | ```js script
4 | import { html } from "@open-wc/demoing-storybook";
5 | import { withKnobs, text, boolean } from "@open-wc/demoing-storybook";
6 | import "./chameleon-toast.js";
7 |
8 | export default {
9 | title: "Components|Overlays/Toast",
10 | component: "chameleon-toast",
11 | decorators: [withKnobs],
12 | options: { selectedPanel: "storybookjs/knobs/panel" },
13 | };
14 | ```
15 |
16 | ## Properties
17 |
18 | | Property Name | Type(s) | Default Value | Description |
19 | | ----------------- | ------- | ------------- | -------------------------------------- |
20 | | `color` | String | `color` | The toast's color |
21 | | `showCloseable` | Boolean | `true` | Whether or not the toast can be closed |
22 | | `backgroundColor` | String | `null` | The toast's background color |
23 |
24 | ## Examples
25 |
26 | ### Default
27 |
28 | ```js preview-story
29 | export const Default = () => {
30 | const color = text("Color", "");
31 | const backgroundColor = text("Background Color", "");
32 | const showCloseable = boolean("Show", true);
33 | const imageUrl = text(
34 | "Image Url",
35 | "https://media.istockphoto.com/photos/chocolate-chip-cookie-isolated-picture-id517109442?k=6&m=517109442&s=612x612&w=0&h=NvQ5y8ENWZvpr84vEFWmxUgV2rCgtOGEsjJXa3IYsZ4="
36 | );
37 | const toastText = text(
38 | "Text",
39 | "This website uses cookies to remember you and improve your experience. By using our site, you accept our use of cookies."
40 | );
41 |
42 | return html`
43 |
48 | ${toastText}
49 |
50 |
51 | `;
52 | };
53 | ```
54 |
--------------------------------------------------------------------------------
/packages/toast/__tests__/chameleon-toast.test.js:
--------------------------------------------------------------------------------
1 | import { ChameleonToast, ChameleonToastStyle } from "../index.js";
2 | import "../chameleon-toast.js";
3 | import { litFixture, html, expect } from "@open-wc/testing";
4 | import sinon from "sinon";
5 |
6 | const fixture = html` `;
7 |
8 | describe("chameleon-toast", () => {
9 | let element;
10 |
11 | beforeEach(async () => {
12 | element = await litFixture(fixture);
13 | });
14 |
15 | it("renders", async () => {
16 | expect(Boolean(element.shadowRoot)).to.equal(true);
17 | });
18 |
19 | it("closes toast", () => {
20 | const dispatchEvent = sinon.spy(element, "dispatchEvent");
21 | const showCloseable = element.showCloseable;
22 |
23 | element.closeToast();
24 |
25 | expect(dispatchEvent).to.be.calledOnce;
26 | expect(element.showCloseable).to.not.equal(showCloseable);
27 | });
28 | });
29 |
--------------------------------------------------------------------------------
/packages/toast/chameleon-toast.js:
--------------------------------------------------------------------------------
1 | import { ChameleonToast } from "./lib/ChameleonToast.js";
2 |
3 | customElements.define("chameleon-toast", ChameleonToast);
4 |
--------------------------------------------------------------------------------
/packages/toast/index.js:
--------------------------------------------------------------------------------
1 | export { ChameleonToast } from "./lib/ChameleonToast.js";
2 | export { ChameleonToastStyle } from "./lib/ChameleonToastStyle.js";
3 |
--------------------------------------------------------------------------------
/packages/toast/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@chameleon-ds/toast",
3 | "version": "2.0.1",
4 | "description": "Chameleon toast",
5 | "author": "Maritz Motivation Solutions, Inc.",
6 | "license": "MIT",
7 | "homepage": "https://github.com/MaritzSTL/chameleon/tree/master/packages/toast#readme",
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/MaritzSTL/chameleon.git"
11 | },
12 | "main": "index.js",
13 | "module": "index.js",
14 | "files": [
15 | "chameleon-toast.js",
16 | "/lib/"
17 | ],
18 | "scripts": {
19 | "test": "echo \"Error: run tests from root\" && exit 1",
20 | "build": "babel src --out-dir lib --config-file ../../babel.config.json"
21 | },
22 | "bugs": {
23 | "url": "https://github.com/MaritzSTL/chameleon/issues"
24 | },
25 | "dependencies": {
26 | "lit-element": "^2.2.1"
27 | },
28 | "publishConfig": {
29 | "access": "public"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/packages/toast/src/ChameleonToast.js:
--------------------------------------------------------------------------------
1 | import { LitElement, html, property } from "lit-element";
2 | import { ChameleonToastStyle } from "./ChameleonToastStyle.js";
3 |
4 | export class ChameleonToast extends LitElement {
5 | /**
6 | * Lifecycle Methods
7 | */
8 | updated(changedProperties) {
9 | if (changedProperties.has("backgroundColor")) {
10 | this.style.backgroundColor = this.backgroundColor ?? "";
11 | }
12 | }
13 |
14 | /**
15 | * Properties
16 | */
17 | // The font color of the toast
18 | @property({ type: String })
19 | color = "";
20 |
21 | // A Boolean which, if true, the toast is visible
22 | @property({ type: Boolean, reflect: true })
23 | showCloseable = true;
24 |
25 | // The background color of the toast
26 | @property({ type: String })
27 | backgroundColor = null;
28 |
29 | /**
30 | * Styles
31 | */
32 | static styles = [ChameleonToastStyle];
33 |
34 | /**
35 | * Template
36 | */
37 | render() {
38 | return html`
39 |
40 |
41 | This website uses cookies to remember you and improve your experience.
42 | By using our site, you accept our use of cookies.
43 |
44 |
45 |
46 | x
47 |
48 | `;
49 | }
50 |
51 | closeToast() {
52 | this.showCloseable = false;
53 |
54 | this.dispatchEvent(
55 | new CustomEvent("close-toast", {
56 | bubbles: true,
57 | composed: true,
58 | })
59 | );
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/packages/toast/src/ChameleonToastStyle.js:
--------------------------------------------------------------------------------
1 | import { css } from "lit-element";
2 |
3 | export const ChameleonToastStyle = css`
4 | :host {
5 | align-items: center;
6 | animation: fadeout 0.5s forwards;
7 | background-color: var(--color-black, #252a33);
8 | border-radius: var(--border-radius, 0.5rem);
9 | bottom: 30px;
10 | box-sizing: border-box;
11 | left: 30px;
12 | color: var(--color-surface, #ffffff);
13 | display: flex;
14 | font-size: var(--font-size-label, 0.875rem);
15 | justify-content: space-between;
16 | line-height: 1.125rem;
17 | padding: 16px 24px;
18 | position: fixed;
19 | width: 456px;
20 | }
21 |
22 | :host([showcloseable]) {
23 | visibility: visible;
24 | animation: fadein 0.5s;
25 | }
26 |
27 | .toast-text {
28 | margin-right: 10px;
29 | }
30 |
31 | .close-icon {
32 | display: flex;
33 | }
34 |
35 | ::slotted([slot="close-icon"]) {
36 | cursor: pointer;
37 | height: 20px;
38 | width: 20px;
39 | border-radius: 50%;
40 | }
41 |
42 | @media only screen and (max-width: 768px) {
43 | :host {
44 | bottom: 10px;
45 | left: 10px;
46 | width: calc(100vw - 20px);
47 | }
48 |
49 | @keyframes fadein {
50 | from {
51 | bottom: 0;
52 | opacity: 0;
53 | }
54 | to {
55 | bottom: 10px;
56 | opacity: 1;
57 | }
58 | }
59 |
60 | @keyframes fadeout {
61 | from {
62 | bottom: 10px;
63 | opacity: 1;
64 | }
65 | to {
66 | bottom: 0;
67 | opacity: 0;
68 | }
69 | }
70 | }
71 |
72 | @keyframes fadein {
73 | from {
74 | bottom: 0;
75 | opacity: 0;
76 | }
77 | to {
78 | bottom: 30px;
79 | opacity: 1;
80 | }
81 | }
82 |
83 | @keyframes fadeout {
84 | from {
85 | bottom: 30px;
86 | opacity: 1;
87 | }
88 | to {
89 | bottom: 0;
90 | opacity: 0;
91 | }
92 | }
93 | `;
94 |
--------------------------------------------------------------------------------
/scripts/linker.js:
--------------------------------------------------------------------------------
1 | // To run this script, install deno,
2 | // ensure you're in root, and:
3 | // deno run --allow-read linker.js
4 |
5 | const packageNames = async () => {
6 | const PACKAGE_DIR = "./packages";
7 |
8 | const packages = await Deno.readDirSync(PACKAGE_DIR);
9 | const names = [];
10 |
11 | for (const entry of packages) {
12 | try {
13 | const rawPackage = Deno.readTextFileSync(
14 | `${PACKAGE_DIR}/${entry.name}/package.json`
15 | );
16 | const packageJson = JSON.parse(rawPackage);
17 | names.push(packageJson.name);
18 | } catch (error) {
19 | // ignore dirs without package.json
20 | }
21 | }
22 |
23 | return names;
24 | };
25 |
26 | const allNames = await packageNames();
27 |
28 | console.log("In this directory, run:");
29 | console.log("");
30 | console.log(`\t npx lerna exec yarn link`);
31 | console.log("");
32 | console.log("To use these in target directory, run:");
33 | console.log("");
34 | console.log(`\t yarn link ${allNames.join(" ")}`);
35 | console.log("");
36 | console.log("To stop using these in target directory, run:");
37 | console.log("");
38 | console.log(`\t yarn unlink ${allNames.join(" ")}`);
39 |
--------------------------------------------------------------------------------