├── .editorconfig ├── .firebaserc ├── .github ├── FUNDING.yml └── workflows │ └── build.yml ├── .gitignore ├── .prettierignore ├── .prettierrc ├── .vscode └── settings.json ├── LICENSE.md ├── README.md ├── angular.json ├── bundlesize.json ├── firebase.json ├── package-lock.json ├── package.json ├── projects ├── docs │ ├── browserslist │ ├── e2e │ │ ├── protractor.conf.js │ │ ├── src │ │ │ ├── app.e2e-spec.ts │ │ │ └── app.po.ts │ │ └── tsconfig.json │ ├── karma.conf.js │ ├── src │ │ ├── app │ │ │ ├── about │ │ │ │ ├── about-routing.module.ts │ │ │ │ ├── about.component.html │ │ │ │ ├── about.component.ts │ │ │ │ └── about.module.ts │ │ │ ├── api │ │ │ │ ├── api-routing.module.ts │ │ │ │ ├── api.component.html │ │ │ │ ├── api.component.ts │ │ │ │ └── api.module.ts │ │ │ ├── app-routing.module.ts │ │ │ ├── app.component.html │ │ │ ├── app.component.scss │ │ │ ├── app.component.ts │ │ │ ├── app.module.ts │ │ │ ├── common │ │ │ │ ├── animations.ts │ │ │ │ ├── core │ │ │ │ │ ├── core.module.ts │ │ │ │ │ └── services │ │ │ │ │ │ ├── api.service.ts │ │ │ │ │ │ ├── router-metadata.service.ts │ │ │ │ │ │ └── theme.service.ts │ │ │ │ ├── enums.ts │ │ │ │ ├── interfaces │ │ │ │ │ └── api.ts │ │ │ │ └── shared │ │ │ │ │ ├── components │ │ │ │ │ ├── book │ │ │ │ │ │ ├── book.component.html │ │ │ │ │ │ ├── book.component.scss │ │ │ │ │ │ └── book.component.ts │ │ │ │ │ ├── component-api │ │ │ │ │ │ ├── component-api.component.html │ │ │ │ │ │ ├── component-api.component.scss │ │ │ │ │ │ └── component-api.component.ts │ │ │ │ │ ├── component-example │ │ │ │ │ │ ├── component-example.component.html │ │ │ │ │ │ ├── component-example.component.scss │ │ │ │ │ │ └── component-example.component.ts │ │ │ │ │ └── theme-api │ │ │ │ │ │ └── theme-api.component.ts │ │ │ │ │ └── shared.module.ts │ │ │ ├── docs │ │ │ │ ├── docs-button │ │ │ │ │ ├── docs-button.component.html │ │ │ │ │ ├── docs-button.component.ts │ │ │ │ │ └── docs-button.module.ts │ │ │ │ ├── docs-card │ │ │ │ │ ├── docs-card.component.html │ │ │ │ │ ├── docs-card.component.ts │ │ │ │ │ └── docs-card.module.ts │ │ │ │ ├── docs-checkbox │ │ │ │ │ ├── docs-checkbox.component.html │ │ │ │ │ ├── docs-checkbox.component.ts │ │ │ │ │ └── docs-checkbox.module.ts │ │ │ │ ├── docs-datalist │ │ │ │ │ ├── docs-datalist.component.html │ │ │ │ │ ├── docs-datalist.component.ts │ │ │ │ │ └── docs-datalist.module.ts │ │ │ │ ├── docs-datepicker │ │ │ │ │ ├── docs-datepicker.component.html │ │ │ │ │ ├── docs-datepicker.component.ts │ │ │ │ │ └── docs-datepicker.module.ts │ │ │ │ ├── docs-forms │ │ │ │ │ ├── docs-forms.component.html │ │ │ │ │ ├── docs-forms.component.ts │ │ │ │ │ └── docs-forms.module.ts │ │ │ │ ├── docs-home │ │ │ │ │ ├── docs-home.component.html │ │ │ │ │ └── docs-home.component.ts │ │ │ │ ├── docs-i18n │ │ │ │ │ ├── docs-i18n.component.html │ │ │ │ │ ├── docs-i18n.component.ts │ │ │ │ │ └── docs-i18n.module.ts │ │ │ │ ├── docs-icons │ │ │ │ │ ├── docs-icons.component.html │ │ │ │ │ ├── docs-icons.component.ts │ │ │ │ │ └── docs-icons.module.ts │ │ │ │ ├── docs-input │ │ │ │ │ ├── docs-input.component.html │ │ │ │ │ ├── docs-input.component.ts │ │ │ │ │ └── docs-input.module.ts │ │ │ │ ├── docs-message │ │ │ │ │ ├── docs-message.component.html │ │ │ │ │ ├── docs-message.component.ts │ │ │ │ │ └── docs-message.module.ts │ │ │ │ ├── docs-modal │ │ │ │ │ ├── docs-modal.component.html │ │ │ │ │ ├── docs-modal.component.ts │ │ │ │ │ └── docs-modal.module.ts │ │ │ │ ├── docs-nav-bar │ │ │ │ │ ├── docs-nav-bar.component.html │ │ │ │ │ ├── docs-nav-bar.component.ts │ │ │ │ │ └── docs-nav-bar.module.ts │ │ │ │ ├── docs-progress │ │ │ │ │ ├── docs-progress.component.html │ │ │ │ │ ├── docs-progress.component.ts │ │ │ │ │ └── docs-progress.module.ts │ │ │ │ ├── docs-radio │ │ │ │ │ ├── docs-radio.component.html │ │ │ │ │ ├── docs-radio.component.ts │ │ │ │ │ └── docs-radio.module.ts │ │ │ │ ├── docs-routing.module.ts │ │ │ │ ├── docs-select │ │ │ │ │ ├── docs-select.component.html │ │ │ │ │ ├── docs-select.component.ts │ │ │ │ │ └── docs-select.module.ts │ │ │ │ ├── docs-side-nav │ │ │ │ │ ├── docs-side-nav.component.html │ │ │ │ │ ├── docs-side-nav.component.ts │ │ │ │ │ └── docs-side-nav.module.ts │ │ │ │ ├── docs-tabs │ │ │ │ │ ├── docs-tabs.component.html │ │ │ │ │ ├── docs-tabs.component.ts │ │ │ │ │ └── docs-tabs.module.ts │ │ │ │ ├── docs-textarea │ │ │ │ │ ├── docs-textarea.component.html │ │ │ │ │ ├── docs-textarea.component.ts │ │ │ │ │ └── docs-textarea.module.ts │ │ │ │ ├── docs-themes │ │ │ │ │ ├── docs-themes.component.html │ │ │ │ │ ├── docs-themes.component.ts │ │ │ │ │ └── docs-themes.module.ts │ │ │ │ ├── docs.component.html │ │ │ │ ├── docs.component.scss │ │ │ │ ├── docs.component.ts │ │ │ │ └── docs.module.ts │ │ │ ├── home │ │ │ │ ├── home.component.html │ │ │ │ ├── home.component.scss │ │ │ │ └── home.component.ts │ │ │ ├── pricing │ │ │ │ ├── pricing-routing.module.ts │ │ │ │ ├── pricing.component.html │ │ │ │ ├── pricing.component.ts │ │ │ │ └── pricing.module.ts │ │ │ └── support │ │ │ │ ├── support-routing.module.ts │ │ │ │ ├── support.component.html │ │ │ │ ├── support.component.ts │ │ │ │ └── support.module.ts │ │ ├── assets │ │ │ ├── .gitkeep │ │ │ ├── images │ │ │ │ ├── angular.svg │ │ │ │ ├── html5.svg │ │ │ │ ├── icon.png │ │ │ │ ├── icons │ │ │ │ │ ├── icon-128x128.png │ │ │ │ │ ├── icon-144x144.png │ │ │ │ │ ├── icon-152x152.png │ │ │ │ │ ├── icon-192x192.png │ │ │ │ │ ├── icon-384x384.png │ │ │ │ │ ├── icon-512x512.png │ │ │ │ │ ├── icon-72x72.png │ │ │ │ │ └── icon-96x96.png │ │ │ │ ├── javascript.svg │ │ │ │ ├── react.svg │ │ │ │ ├── vue.svg │ │ │ │ └── web-components-and-frameworks-small.png │ │ │ └── plain.html │ │ ├── environments │ │ │ ├── environment.prod.ts │ │ │ └── environment.ts │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── main.ts │ │ ├── manifest.json │ │ ├── polyfills.ts │ │ ├── robots.txt │ │ ├── sitemap.xml │ │ ├── styles.scss │ │ ├── styles │ │ │ ├── _layout.scss │ │ │ ├── _logo.scss │ │ │ ├── _theme.scss │ │ │ ├── _typography.scss │ │ │ └── _variables.scss │ │ └── test.ts │ ├── tsconfig.app.json │ ├── tsconfig.prod.json │ ├── tsconfig.spec.json │ └── tslint.json └── lithium │ ├── LICENSE-MIT.md │ ├── button │ ├── button-group.element.scss │ ├── button-group.element.spec.ts │ ├── button-group.element.ts │ ├── button.element.scss │ ├── button.element.spec.ts │ ├── button.element.ts │ ├── entrypoint.tsconfig.json │ ├── index.ts │ └── package.json │ ├── card │ ├── card-actions.element.scss │ ├── card-actions.element.ts │ ├── card-content.element.scss │ ├── card-content.element.ts │ ├── card-header.element.scss │ ├── card-header.element.ts │ ├── card.element.scss │ ├── card.element.spec.ts │ ├── card.element.ts │ ├── entrypoint.tsconfig.json │ ├── index.ts │ └── package.json │ ├── checkbox │ ├── checkbox-group.element.scss │ ├── checkbox-group.element.spec.ts │ ├── checkbox-group.element.ts │ ├── checkbox.element.scss │ ├── checkbox.element.spec.ts │ ├── checkbox.element.ts │ ├── entrypoint.tsconfig.json │ ├── index.ts │ └── package.json │ ├── code-example │ ├── code-example.element.scss │ ├── code-example.element.spec.ts │ ├── code-example.element.ts │ ├── entrypoint.tsconfig.json │ ├── index.ts │ └── package.json │ ├── common │ ├── base │ │ ├── base.element.scss │ │ └── button.base.ts │ ├── decorators │ │ ├── event.spec.ts │ │ ├── event.ts │ │ ├── property.spec.ts │ │ ├── property.ts │ │ ├── query-slot.spec.ts │ │ └── query-slot.ts │ ├── entrypoint.tsconfig.json │ ├── index.ts │ ├── package.json │ ├── services │ │ ├── i18n.service.spec.ts │ │ └── i18n.service.ts │ └── utils │ │ ├── enums.ts │ │ ├── events.ts │ │ └── register.ts │ ├── datalist │ ├── datalist.element.spec.ts │ ├── datalist.element.ts │ ├── entrypoint.tsconfig.json │ ├── index.ts │ └── package.json │ ├── datepicker │ ├── datepicker-inline.element.scss │ ├── datepicker-inline.element.spec.ts │ ├── datepicker-inline.element.ts │ ├── datepicker.element.scss │ ├── datepicker.element.spec.ts │ ├── datepicker.element.ts │ ├── entrypoint.tsconfig.json │ ├── index.ts │ ├── package.json │ ├── util.spec.ts │ └── util.ts │ ├── dropdown │ ├── dropdown.element.scss │ ├── dropdown.element.spec.ts │ ├── dropdown.element.ts │ ├── entrypoint.tsconfig.json │ ├── index.ts │ └── package.json │ ├── form │ ├── entrypoint.tsconfig.json │ ├── form.element.scss │ ├── form.element.spec.ts │ ├── form.element.ts │ ├── index.ts │ └── package.json │ ├── icon-shapes │ ├── entrypoint.tsconfig.json │ ├── icon.element.scss │ ├── icon.element.spec.ts │ ├── icon.element.ts │ ├── icon.service.spec.ts │ ├── icon.service.ts │ ├── index.ts │ ├── package.json │ └── svg.ts │ ├── icon │ ├── entrypoint.tsconfig.json │ ├── index.ts │ └── package.json │ ├── index.ts │ ├── input │ ├── entrypoint.tsconfig.json │ ├── index.ts │ ├── input-error.element.scss │ ├── input-error.element.ts │ ├── input-error.spec.ts │ ├── input-message.element.scss │ ├── input-message.element.ts │ ├── input-message.spec.ts │ ├── input.element.scss │ ├── input.element.spec.ts │ ├── input.element.ts │ └── package.json │ ├── karma.conf.js │ ├── message │ ├── entrypoint.tsconfig.json │ ├── index.ts │ ├── message.element.scss │ ├── message.element.spec.ts │ ├── message.element.ts │ └── package.json │ ├── modal │ ├── entrypoint.tsconfig.json │ ├── index.ts │ ├── modal-actions.element.ts │ ├── modal-content.element.ts │ ├── modal-header.element.ts │ ├── modal.element.scss │ ├── modal.element.spec.ts │ ├── modal.element.ts │ └── package.json │ ├── nav-bar │ ├── entrypoint.tsconfig.json │ ├── index.ts │ ├── nav-bar.element.scss │ ├── nav-bar.element.spec.ts │ ├── nav-bar.element.ts │ └── package.json │ ├── package.js │ ├── package.json │ ├── pro │ ├── LICENSE.md │ └── README.md │ ├── progress │ ├── entrypoint.tsconfig.json │ ├── index.ts │ ├── package.json │ ├── progress.element.scss │ ├── progress.element.spec.ts │ └── progress.element.ts │ ├── radio │ ├── entrypoint.tsconfig.json │ ├── index.ts │ ├── package.json │ ├── radio-group.element.scss │ ├── radio-group.element.spec.ts │ ├── radio-group.element.ts │ ├── radio.element.scss │ ├── radio.element.spec.ts │ └── radio.element.ts │ ├── sass-template.js │ ├── select │ ├── entrypoint.tsconfig.json │ ├── index.ts │ ├── package.json │ ├── select.element.spec.ts │ └── select.element.ts │ ├── side-nav │ ├── entrypoint.tsconfig.json │ ├── index.ts │ ├── package.json │ ├── side-nav.element.scss │ ├── side-nav.element.spec.ts │ └── side-nav.element.ts │ ├── styles │ ├── _a11y.scss │ ├── _base.element.scss │ ├── _utils.scss │ └── _variables.scss │ ├── switch │ ├── entrypoint.tsconfig.json │ ├── index.ts │ ├── package.json │ ├── switch.element.scss │ ├── switch.element.spec.ts │ └── switch.element.ts │ ├── tabs │ ├── entrypoint.tsconfig.json │ ├── index.ts │ ├── package.json │ ├── tab-title.element.spec.ts │ ├── tab-title.element.ts │ ├── tab.element.scss │ ├── tab.element.spec.ts │ ├── tab.element.ts │ ├── tabs.element.scss │ ├── tabs.element.spec.ts │ └── tabs.element.ts │ ├── test-bundles │ ├── README.md │ ├── bundlesize.json │ ├── index.js │ └── webpack.config.js │ ├── test.ts │ ├── test │ └── utils.ts │ ├── textarea │ ├── entrypoint.tsconfig.json │ ├── index.ts │ ├── package.json │ ├── textarea.element.spec.ts │ └── textarea.element.ts │ ├── tsconfig.json │ ├── tsconfig.lib.json │ ├── tsconfig.project.json │ ├── tsconfig.spec.json │ └── tslint.json ├── tsconfig.json └── tslint.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.firebaserc: -------------------------------------------------------------------------------- 1 | { 2 | "projects": { 3 | "default": "sites-fc2cf" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: coryrylan # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: https://lithiumui.dev/pricing # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | on: 3 | push: 4 | branches: 5 | - master 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | strategy: 11 | matrix: 12 | node-version: [12.x] 13 | 14 | steps: 15 | - uses: actions/checkout@v1 16 | 17 | - name: Cache node modules 18 | uses: actions/cache@v1 19 | with: 20 | path: ~/.npm 21 | key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} 22 | restore-keys: | 23 | ${{ runner.os }}-node- 24 | 25 | - name: Node ${{ matrix.node-version }} 26 | uses: actions/setup-node@v1 27 | with: 28 | node-version: ${{ matrix.node-version }} 29 | - name: npm ci and npm run build 30 | run: | 31 | npm ci 32 | npm run build -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | *.element.css.ts 4 | 5 | # compiled output 6 | /dist 7 | /tmp 8 | /out-tsc 9 | /api 10 | /projects/docs/api 11 | .firebase 12 | # Only exists if Bazel was run 13 | /bazel-out 14 | 15 | # dependencies 16 | /node_modules 17 | 18 | # profiling files 19 | chrome-profiler-events*.json 20 | speed-measure-plugin*.json 21 | 22 | # IDEs and editors 23 | /.idea 24 | .project 25 | .classpath 26 | .c9/ 27 | *.launch 28 | .settings/ 29 | *.sublime-workspace 30 | 31 | # IDE - VSCode 32 | .vscode/* 33 | !.vscode/settings.json 34 | !.vscode/tasks.json 35 | !.vscode/launch.json 36 | !.vscode/extensions.json 37 | .history/* 38 | 39 | # misc 40 | /.sass-cache 41 | /connect.lock 42 | /coverage 43 | /libpeerconnection.log 44 | npm-debug.log 45 | yarn-error.log 46 | testem.log 47 | /typings 48 | 49 | # System Files 50 | .DS_Store 51 | Thumbs.db 52 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | *.element.css.ts -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 140, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "semi": true, 6 | "singleQuote": true, 7 | "bracketSpacing": true, 8 | "arrowParens": "avoid" 9 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.exclude": { 3 | "**/*.element.css.ts": true 4 | } 5 | } -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT or Polyform Noncommercial License 1.0.0 2 | 3 | All standard components (non Pro Components) are released under [MIT License](https://github.com/coryrylan/lithium/tree/master/projects/lithium/LICENSE-MIT.md). 4 | 5 | [Pro Components](https://github.com/coryrylan/lithium/tree/master/projects/lithium/pro) released under [non-commercial license](https://polyformproject.org/licenses/noncommercial/1.0.0) 6 | and can be used commercially with purchase of a [Lithium Pro Component License](lithiumui.dev/pricing). -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Lithium (Beta) 2 | 3 | [![build status](https://github.com/coryrylan/lithium/workflows/Build/badge.svg)](https://github.com/coryrylan/lithium/actions) 4 | [![npm version](https://badge.fury.io/js/lithium-ui.svg)](https://badge.fury.io/js/lithium-ui) 5 | 6 | ## Lightweight UI Components that work everywhere. 7 | 8 | Fast, modern Web Components that work in any JavaScript framework. Built on the 9 | latest web standards, Lithium lets you include only the components you need. 10 | 11 | Lithium Web Components are themable and can work in any Web stack. Open Source. 12 | 13 | ### [Documentation](https://lithiumui.dev/) 14 | 15 | ```javascript 16 | import 'lithium-ui/modal'; 17 | 18 | const modal = document.querySelector('li-modal'); 19 | modal.toggle(); 20 | ``` 21 | 22 | ```html 23 | 24 | Hello World 25 | 26 | ``` 27 | 28 | ### License 29 | 30 | All standard components (non Pro Components) are released under [MIT License](https://opensource.org/licenses/MIT). 31 | 32 | [Pro Components](https://github.com/coryrylan/lithium/tree/master/projects/lithium/pro) released under [non-commercial license](https://polyformproject.org/licenses/noncommercial/1.0.0) 33 | and can be used commercially with purchase of a [Lithium Pro Component License](https://lithiumui.dev/pricing). -------------------------------------------------------------------------------- /bundlesize.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | { 4 | "path": "./dist/lithium/index.js", 5 | "maxSize": "6 kB" 6 | }, 7 | { 8 | "path": "./dist/lithium/**/*.js", 9 | "maxSize": "10 kB" 10 | }, 11 | { 12 | "path": "./dist/docs/styles.*.css", 13 | "maxSize": "5 kB" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "hosting": { 3 | "public": "dist/docs", 4 | "ignore": [ 5 | "firebase.json", 6 | "**/.*", 7 | "**/node_modules/**" 8 | ], 9 | "rewrites": [ 10 | { 11 | "source": "**", 12 | "destination": "/index.html" 13 | } 14 | ], 15 | "headers": [ 16 | { 17 | "source": "**/*.@(eot|otf|ttf|ttc|woff|font.css)", 18 | "headers": [ 19 | { 20 | "key": "Access-Control-Allow-Origin", 21 | "value": "*" 22 | } 23 | ] 24 | }, 25 | { 26 | "source": "**/*.@(jpg|jpeg|gif|png|svg)", 27 | "headers": [ 28 | { 29 | "key": "Cache-Control", 30 | "value": "max-age=31536000" 31 | } 32 | ] 33 | }, 34 | { 35 | "source": "**/*.@(css)", 36 | "headers": [ 37 | { 38 | "key": "Cache-Control", 39 | "value": "max-age=31536000" 40 | } 41 | ] 42 | }, 43 | { 44 | "source": "**/*.@(js)", 45 | "headers": [ 46 | { 47 | "key": "Cache-Control", 48 | "value": "max-age=31536000" 49 | } 50 | ] 51 | } 52 | ] 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /projects/docs/browserslist: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # You can see what browsers were selected by your queries by running: 6 | # npx browserslist 7 | 8 | > 0.5% 9 | last 2 versions 10 | Firefox ESR 11 | not dead 12 | not IE 9-11 # For IE 9-11 support, remove 'not'. -------------------------------------------------------------------------------- /projects/docs/e2e/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | // Protractor configuration file, see link for more information 3 | // https://github.com/angular/protractor/blob/master/lib/config.ts 4 | 5 | const { SpecReporter } = require('jasmine-spec-reporter'); 6 | 7 | /** 8 | * @type { import("protractor").Config } 9 | */ 10 | exports.config = { 11 | allScriptsTimeout: 11000, 12 | specs: [ 13 | './src/**/*.e2e-spec.ts' 14 | ], 15 | capabilities: { 16 | browserName: 'chrome' 17 | }, 18 | directConnect: true, 19 | baseUrl: 'http://localhost:4200/', 20 | framework: 'jasmine', 21 | jasmineNodeOpts: { 22 | showColors: true, 23 | defaultTimeoutInterval: 30000, 24 | print: function() {} 25 | }, 26 | onPrepare() { 27 | require('ts-node').register({ 28 | project: require('path').join(__dirname, './tsconfig.json') 29 | }); 30 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 31 | } 32 | }; -------------------------------------------------------------------------------- /projects/docs/e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { browser, logging } from 'protractor'; 2 | import { AppPage } from './app.po'; 3 | 4 | describe('workspace-project App', () => { 5 | let page: AppPage; 6 | 7 | beforeEach(() => { 8 | page = new AppPage(); 9 | }); 10 | 11 | it('should display welcome message', () => { 12 | page.navigateTo(); 13 | expect(page.getTitleText()).toEqual('docs app is running!'); 14 | }); 15 | 16 | afterEach(async () => { 17 | // Assert that there are no errors emitted from the browser 18 | const logs = await browser 19 | .manage() 20 | .logs() 21 | .get(logging.Type.BROWSER); 22 | expect(logs).not.toContain( 23 | jasmine.objectContaining({ 24 | level: logging.Level.SEVERE 25 | } as logging.Entry) 26 | ); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /projects/docs/e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo() { 5 | return browser.get(browser.baseUrl) as Promise; 6 | } 7 | 8 | getTitleText() { 9 | return element(by.css('app-root .content span')).getText() as Promise; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /projects/docs/e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../../out-tsc/e2e", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "types": [ 8 | "jasmine", 9 | "jasminewd2", 10 | "node" 11 | ] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /projects/docs/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, '../../coverage/docs'), 20 | reports: ['html', 'lcovonly', 'text-summary'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false, 30 | restartOnFileChange: true 31 | }); 32 | }; 33 | -------------------------------------------------------------------------------- /projects/docs/src/app/about/about-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | 4 | import { AboutComponent } from './about.component'; 5 | 6 | const routes: Routes = [{ path: '', component: AboutComponent }]; 7 | 8 | @NgModule({ 9 | imports: [RouterModule.forChild(routes)], 10 | exports: [RouterModule] 11 | }) 12 | export class AboutRoutingModule {} 13 | -------------------------------------------------------------------------------- /projects/docs/src/app/about/about.component.html: -------------------------------------------------------------------------------- 1 |

About

2 | -------------------------------------------------------------------------------- /projects/docs/src/app/about/about.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-about', 5 | templateUrl: './about.component.html' 6 | }) 7 | export class AboutComponent implements OnInit { 8 | constructor() {} 9 | 10 | ngOnInit() {} 11 | } 12 | -------------------------------------------------------------------------------- /projects/docs/src/app/about/about.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; 3 | 4 | import { AboutRoutingModule } from './about-routing.module'; 5 | import { AboutComponent } from './about.component'; 6 | 7 | @NgModule({ 8 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 9 | imports: [CommonModule, AboutRoutingModule], 10 | declarations: [AboutComponent] 11 | }) 12 | export class AboutModule {} 13 | -------------------------------------------------------------------------------- /projects/docs/src/app/api/api-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | 4 | import { ApiComponent } from './api.component'; 5 | 6 | const routes: Routes = [{ path: '', component: ApiComponent }]; 7 | 8 | @NgModule({ 9 | imports: [RouterModule.forChild(routes)], 10 | exports: [RouterModule] 11 | }) 12 | export class ApiRoutingModule {} 13 | -------------------------------------------------------------------------------- /projects/docs/src/app/api/api.component.html: -------------------------------------------------------------------------------- 1 |

Reference API

2 | 3 | 4 | 5 | 6 | 7 |

8 | 9 |
10 | 11 |
12 | -------------------------------------------------------------------------------- /projects/docs/src/app/api/api.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { FormControl } from '@angular/forms'; 3 | import { ApiService } from '../common/core/services/api.service'; 4 | import { ClassType } from '../common/interfaces/api'; 5 | 6 | @Component({ 7 | selector: 'app-api', 8 | templateUrl: './api.component.html' 9 | }) 10 | export class ApiComponent implements OnInit { 11 | search = new FormControl(''); 12 | classResults: ClassType[] = []; 13 | private classes: ClassType[] = []; 14 | 15 | constructor(private apiService: ApiService) { 16 | this.apiService.api.subscribe(classes => { 17 | this.classes = classes; 18 | this.classResults = this.classes; 19 | }); 20 | 21 | this.search.valueChanges.subscribe(query => { 22 | if (query.length) { 23 | this.classResults = this.classes.filter(c => c.name.toLowerCase().includes(query.toLowerCase())); 24 | } else { 25 | this.classResults = this.classes; 26 | } 27 | }); 28 | } 29 | 30 | ngOnInit() {} 31 | } 32 | -------------------------------------------------------------------------------- /projects/docs/src/app/api/api.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { HttpClientModule } from '@angular/common/http'; 3 | import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; 4 | import { ReactiveFormsModule } from '@angular/forms'; 5 | 6 | import { SharedModule } from '../common/shared/shared.module'; 7 | import { ApiRoutingModule } from './api-routing.module'; 8 | import { ApiComponent } from './api.component'; 9 | 10 | @NgModule({ 11 | declarations: [ApiComponent], 12 | imports: [CommonModule, SharedModule, HttpClientModule, ReactiveFormsModule, ApiRoutingModule], 13 | schemas: [CUSTOM_ELEMENTS_SCHEMA] 14 | }) 15 | export class ApiModule {} 16 | -------------------------------------------------------------------------------- /projects/docs/src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | 4 | import { Layout } from './common/enums'; 5 | import { HomeComponent } from './home/home.component'; 6 | 7 | const routes: Routes = [ 8 | { path: '', component: HomeComponent, data: { title: 'Lithium UI - Web Component Library', layout: Layout.Page } }, 9 | { 10 | path: 'docs', 11 | loadChildren: () => import('./docs/docs.module').then(m => m.DocsModule), 12 | data: { title: 'Lithium - Documentation', layout: Layout.Docs } 13 | }, 14 | { 15 | path: 'about', 16 | loadChildren: () => import('./about/about.module').then(m => m.AboutModule), 17 | data: { title: 'Lithium - About', layout: Layout.Page } 18 | }, 19 | { 20 | path: 'support', 21 | loadChildren: () => import('./support/support.module').then(m => m.SupportModule), 22 | data: { title: 'Lithium - Support', layout: Layout.Page } 23 | }, 24 | { 25 | path: 'api', 26 | loadChildren: () => import('./api/api.module').then(m => m.ApiModule), 27 | data: { title: 'Lithium - API Reference', layout: Layout.Page } 28 | }, 29 | { 30 | path: 'pricing', 31 | loadChildren: () => import('./pricing/pricing.module').then(m => m.PricingModule), 32 | data: { title: 'Lithium - Pricing', layout: Layout.Page } 33 | } 34 | ]; 35 | 36 | @NgModule({ 37 | imports: [RouterModule.forRoot(routes, { scrollPositionRestoration: 'enabled' })], 38 | exports: [RouterModule] 39 | }) 40 | export class AppRoutingModule {} 41 | -------------------------------------------------------------------------------- /projects/docs/src/app/app.component.scss: -------------------------------------------------------------------------------- 1 | @import './../styles/variables'; 2 | 3 | main { 4 | min-height: 100vh; 5 | } 6 | 7 | footer { 8 | padding: 1.2rem; 9 | margin-top: 1.2rem; 10 | font-size: 1.6rem; 11 | } 12 | 13 | li-nav-bar a, 14 | li-nav-bar button { 15 | display: none; 16 | 17 | @media (min-width: $nav-breakpoint) { 18 | display: flex; 19 | } 20 | } 21 | 22 | .mobile-only { 23 | display: flex !important; 24 | 25 | @media (min-width: $nav-breakpoint) { 26 | display: none !important; 27 | } 28 | } 29 | 30 | .docs-nav { 31 | @media (min-width: $nav-breakpoint) { 32 | --li-side-nav-top: 5.6rem; 33 | --li-side-nav-width: 28rem; 34 | position: absolute; 35 | z-index: 99; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /projects/docs/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import 'lithium-ui/icon'; 3 | import { IconService, menuIcon } from 'lithium-ui/icon-shapes'; 4 | IconService.addIcons(menuIcon); 5 | 6 | import { environment } from '../environments/environment'; 7 | import { fadeAnimation } from './common/animations'; 8 | import { RouterMetaDataService } from './common/core/services/router-metadata.service'; 9 | import { ThemeService } from './common/core/services/theme.service'; 10 | 11 | @Component({ 12 | selector: 'app-root', 13 | templateUrl: './app.component.html', 14 | styleUrls: ['./app.component.scss'], 15 | animations: [fadeAnimation] 16 | }) 17 | export class AppComponent { 18 | version = environment.version; 19 | sticky = false; 20 | openMenu = false; 21 | 22 | constructor(private routerMetaDataService: RouterMetaDataService, private themeService: ThemeService) { 23 | this.routerMetaDataService.init().subscribe(); 24 | this.themeService.init(); 25 | } 26 | 27 | toggleTheme() { 28 | this.themeService.toggleTheme(); 29 | } 30 | 31 | toggleMenu() { 32 | this.openMenu = !this.openMenu; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /projects/docs/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; 2 | import { BrowserModule } from '@angular/platform-browser'; 3 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; 4 | 5 | import 'lithium-ui/button'; 6 | import 'lithium-ui/card'; 7 | import 'lithium-ui/checkbox'; 8 | import 'lithium-ui/code-example'; 9 | import 'lithium-ui/datalist'; 10 | import 'lithium-ui/datepicker'; 11 | import 'lithium-ui/dropdown'; 12 | import 'lithium-ui/form'; 13 | import 'lithium-ui/input'; 14 | import 'lithium-ui/message'; 15 | import 'lithium-ui/modal'; 16 | import 'lithium-ui/nav-bar'; 17 | import 'lithium-ui/progress'; 18 | import 'lithium-ui/radio'; 19 | import 'lithium-ui/select'; 20 | import 'lithium-ui/side-nav'; 21 | import 'lithium-ui/switch'; 22 | import 'lithium-ui/tabs'; 23 | import 'lithium-ui/textarea'; 24 | 25 | import { AppRoutingModule } from './app-routing.module'; 26 | import { AppComponent } from './app.component'; 27 | import { CoreModule } from './common/core/core.module'; 28 | import { SharedModule } from './common/shared/shared.module'; 29 | import { HomeComponent } from './home/home.component'; 30 | 31 | @NgModule({ 32 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 33 | declarations: [AppComponent, HomeComponent], 34 | imports: [BrowserModule, AppRoutingModule, BrowserAnimationsModule, CoreModule, SharedModule], 35 | providers: [], 36 | bootstrap: [AppComponent] 37 | }) 38 | export class AppModule {} 39 | -------------------------------------------------------------------------------- /projects/docs/src/app/common/animations.ts: -------------------------------------------------------------------------------- 1 | import { animate, query, style, transition, trigger } from '@angular/animations'; 2 | 3 | export const fadeAnimation = trigger('fadeAnimation', [ 4 | transition('* => *', [ 5 | query(':enter', [style({ opacity: 0, height: 0 })], { optional: true }), 6 | query(':enter', [style({ opacity: 0, height: 'auto' }), animate('0.4s', style({ opacity: 1 }))], { optional: true }) 7 | ]) 8 | ]); 9 | -------------------------------------------------------------------------------- /projects/docs/src/app/common/core/core.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { HttpClientModule } from '@angular/common/http'; 3 | import { NgModule, Optional, SkipSelf } from '@angular/core'; 4 | 5 | import { RouterMetaDataService } from './services/router-metadata.service'; 6 | import { ThemeService } from './services/theme.service'; 7 | 8 | @NgModule({ 9 | imports: [CommonModule, HttpClientModule], 10 | providers: [RouterMetaDataService, ThemeService] 11 | }) 12 | export class CoreModule { 13 | constructor(@Optional() @SkipSelf() parentModule: CoreModule) { 14 | if (parentModule) { 15 | throw new Error('CoreModule has already been loaded'); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /projects/docs/src/app/common/core/services/api.service.ts: -------------------------------------------------------------------------------- 1 | import { HttpClient } from '@angular/common/http'; 2 | import { Injectable } from '@angular/core'; 3 | import { Observable } from 'rxjs'; 4 | import { map, shareReplay } from 'rxjs/operators'; 5 | 6 | import { ClassType } from '../../interfaces/api'; 7 | 8 | @Injectable({ 9 | providedIn: 'root' 10 | }) 11 | export class ApiService { 12 | api: Observable; 13 | 14 | constructor(private httpClient: HttpClient) { 15 | this.api = this.httpClient.get('/assets/api.json').pipe( 16 | map(data => data), 17 | // map(classes => this.removeMarkdown(classes)), 18 | shareReplay() 19 | ); 20 | } 21 | 22 | // private removeMarkdown(classes: Class[]) { 23 | // classes.filter(c => c.comment).forEach(c => c.comment.tags.forEach(t => (t.text = t.text.replace(/`/g, '')))); 24 | 25 | // return classes; 26 | // } 27 | } 28 | -------------------------------------------------------------------------------- /projects/docs/src/app/common/core/services/theme.service.ts: -------------------------------------------------------------------------------- 1 | import { DOCUMENT } from '@angular/common'; 2 | import { Inject, Injectable, Renderer2, RendererFactory2 } from '@angular/core'; 3 | 4 | @Injectable({ 5 | providedIn: 'root' 6 | }) 7 | export class ThemeService { 8 | private renderer: Renderer2; 9 | 10 | get theme() { 11 | const value = `${localStorage.getItem('lithium-theme') ? localStorage.getItem('lithium-theme') : 'light-theme'}`; 12 | return value; 13 | } 14 | 15 | set theme(value: string) { 16 | this.renderer.removeClass(document.body, this.theme); 17 | this.renderer.addClass(document.body, value); 18 | localStorage.setItem('lithium-theme', value); 19 | } 20 | 21 | constructor(rendererFactory: RendererFactory2, @Inject(DOCUMENT) private document: any) { 22 | this.renderer = rendererFactory.createRenderer(null, null); 23 | } 24 | 25 | init() { 26 | this.renderer.addClass(this.document.body, this.theme); 27 | } 28 | 29 | toggleTheme() { 30 | this.theme = this.theme === 'light-theme' ? 'dark-theme' : 'light-theme'; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /projects/docs/src/app/common/enums.ts: -------------------------------------------------------------------------------- 1 | export enum Layout { 2 | Page = 'layout-page', 3 | Docs = 'layout-docs' 4 | } 5 | -------------------------------------------------------------------------------- /projects/docs/src/app/common/interfaces/api.ts: -------------------------------------------------------------------------------- 1 | export interface CallSignature { 2 | id: number; 3 | name: string; 4 | kind: 4096; 5 | kindString: 'Call signature'; 6 | flags: {}; 7 | comment: { 8 | shortText: string; 9 | }; 10 | type: { 11 | type: string; 12 | name: string; 13 | }; 14 | } 15 | 16 | export interface Method { 17 | comment: { 18 | shortText: string; 19 | }; 20 | flags: { 21 | isStatic: boolean; 22 | isExported: boolean; 23 | }; 24 | id: number; 25 | kind: number; 26 | kindString: 'Method'; 27 | name: string; 28 | signatures: CallSignature[]; 29 | } 30 | 31 | export interface Property { 32 | comment: { 33 | shortText: string; 34 | }; 35 | decorators: any[]; 36 | defaultValue: string; 37 | flags: { 38 | isExported: boolean; 39 | }; 40 | id: number; 41 | kind: number; 42 | kindString: 'Property'; 43 | name: string; 44 | } 45 | 46 | export interface ClassType { 47 | comment: { 48 | shortText: string; 49 | tags: { tag: string; text: string }[]; 50 | }; 51 | id: number; 52 | kind: 128; 53 | kindString: string; 54 | name: string; 55 | children: Property | Method[]; 56 | } 57 | -------------------------------------------------------------------------------- /projects/docs/src/app/common/shared/components/book/book.component.scss: -------------------------------------------------------------------------------- 1 | @import './../../../../../styles//variables'; 2 | 3 | li-card { 4 | --padding: 1.6rem; 5 | max-width: 25rem; 6 | text-align: center; 7 | margin-top: 2.4rem; 8 | 9 | @media (min-width: $book-ad-breakpoint) { 10 | position: fixed; 11 | top: 5.6rem; 12 | right: 2.4rem; 13 | } 14 | 15 | h3 { 16 | font-size: 1.8rem; 17 | margin-bottom: 1rem; 18 | } 19 | 20 | p { 21 | margin-bottom: 1.4rem; 22 | } 23 | 24 | span { 25 | color: #4292dd; 26 | } 27 | 28 | img { 29 | width: 100%; 30 | max-width: 15rem; 31 | margin: 0 auto; 32 | display: block; 33 | margin-bottom: 1.8rem; 34 | } 35 | 36 | li-button { 37 | margin-bottom: 0; 38 | } 39 | } 40 | 41 | a { 42 | text-decoration: none; 43 | } 44 | -------------------------------------------------------------------------------- /projects/docs/src/app/common/shared/components/book/book.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-book', 5 | templateUrl: './book.component.html', 6 | styleUrls: ['./book.component.scss'] 7 | }) 8 | export class BookComponent {} 9 | -------------------------------------------------------------------------------- /projects/docs/src/app/common/shared/components/component-api/component-api.component.scss: -------------------------------------------------------------------------------- 1 | h2, 2 | h3, 3 | table { 4 | margin-top: 0; 5 | margin-bottom: 0.5rem; 6 | } 7 | 8 | table { 9 | width: 100%; 10 | padding: 2rem 0; 11 | margin-bottom: 2rem; 12 | border-bottom: 1px solid var(--global-color-gray-300); 13 | } 14 | 15 | th { 16 | text-align: left; 17 | } 18 | 19 | th, 20 | td { 21 | padding: 0.5rem; 22 | width: 33.33%; 23 | } 24 | -------------------------------------------------------------------------------- /projects/docs/src/app/common/shared/components/component-api/component-api.component.ts: -------------------------------------------------------------------------------- 1 | import { HttpClient } from '@angular/common/http'; 2 | import { Component, Input, OnInit } from '@angular/core'; 3 | import { Observable } from 'rxjs'; 4 | import { map } from 'rxjs/operators'; 5 | 6 | interface ElementDoc { 7 | name: string; 8 | description: string; 9 | jsDoc: string; 10 | attributes: { name: string; description: string; type: string }[]; 11 | properties: { name: string; description: string; jsDoc: string; type: string }[]; 12 | events: { name: string; description: string; type: string }[]; 13 | slots: { name: string; description: string }[]; 14 | cssProperties: { name: string }[]; 15 | } 16 | 17 | interface Docs { 18 | version: number; 19 | tags: ElementDoc[]; 20 | } 21 | 22 | @Component({ 23 | selector: 'app-component-api', 24 | templateUrl: './component-api.component.html', 25 | styleUrls: ['./component-api.component.scss'] 26 | }) 27 | export class ComponentApiComponent implements OnInit { 28 | @Input() element = ''; 29 | 30 | el: Observable; 31 | 32 | constructor(private http: HttpClient) {} 33 | 34 | ngOnInit() { 35 | this.el = this.http.get(`/api/${this.element}.json`).pipe(map(v => v.tags[0])); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /projects/docs/src/app/common/shared/components/component-example/component-example.component.html: -------------------------------------------------------------------------------- 1 | 2 | {{ example.key }} 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /projects/docs/src/app/common/shared/components/component-example/component-example.component.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | display: block; 3 | max-width: 70rem; 4 | margin-bottom: 8rem; 5 | 6 | // @media (min-width: 1024px) { 7 | // margin: 0 2rem; 8 | // } 9 | } 10 | 11 | li-tabs { 12 | --li-tabs-button-selected-border-color: var(--global-color-gray-300); 13 | } 14 | 15 | li-tab-title { 16 | text-transform: uppercase; 17 | } 18 | -------------------------------------------------------------------------------- /projects/docs/src/app/common/shared/components/component-example/component-example.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-component-example', 5 | templateUrl: './component-example.component.html', 6 | styleUrls: ['./component-example.component.scss'] 7 | }) 8 | export class ComponentExampleComponent implements OnInit { 9 | @Input() code: any = {}; 10 | 11 | constructor() {} 12 | 13 | ngOnInit() {} 14 | } 15 | -------------------------------------------------------------------------------- /projects/docs/src/app/common/shared/components/theme-api/theme-api.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-theme-api', 5 | template: ` 6 |

Theme API

7 | ` 8 | }) 9 | export class ThemeAPIComponent implements OnInit { 10 | constructor() {} 11 | 12 | ngOnInit() {} 13 | } 14 | -------------------------------------------------------------------------------- /projects/docs/src/app/common/shared/shared.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; 3 | import { ReactiveFormsModule } from '@angular/forms'; 4 | 5 | import { BookComponent } from './components/book/book.component'; 6 | import { ComponentApiComponent } from './components/component-api/component-api.component'; 7 | import { ComponentExampleComponent } from './components/component-example/component-example.component'; 8 | import { ThemeAPIComponent } from './components/theme-api/theme-api.component'; 9 | 10 | const components = [ComponentApiComponent, ThemeAPIComponent, BookComponent, ComponentExampleComponent]; 11 | 12 | @NgModule({ 13 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 14 | imports: [CommonModule, ReactiveFormsModule], 15 | declarations: [...components, ComponentApiComponent], 16 | exports: [...components, ReactiveFormsModule] 17 | }) 18 | export class SharedModule {} 19 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-button/docs-button.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; 3 | import { RouterModule, Routes } from '@angular/router'; 4 | 5 | import { SharedModule } from '../../common/shared/shared.module'; 6 | import { DocsButtonComponent } from './docs-button.component'; 7 | 8 | const routes: Routes = [{ path: '', component: DocsButtonComponent }]; 9 | 10 | @NgModule({ 11 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 12 | imports: [RouterModule.forChild(routes), CommonModule, SharedModule], 13 | declarations: [DocsButtonComponent] 14 | }) 15 | export class DocsButtonModule {} 16 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-card/docs-card.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; 3 | import { RouterModule, Routes } from '@angular/router'; 4 | 5 | import { DocsCardComponent } from './docs-card.component'; 6 | 7 | const routes: Routes = [{ path: '', component: DocsCardComponent }]; 8 | 9 | @NgModule({ 10 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 11 | imports: [RouterModule.forChild(routes), CommonModule], 12 | declarations: [DocsCardComponent] 13 | }) 14 | export class DocsCardModule {} 15 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-checkbox/docs-checkbox.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-docs-checkbox', 5 | templateUrl: './docs-checkbox.component.html' 6 | }) 7 | export class DocsCheckboxComponent { 8 | codeExampleImport = ` 9 | import 'lithium-ui/checkbox'; 10 | `; 11 | 12 | codeExampleHtml = ` 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | Select at least one 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | `; 41 | } 42 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-checkbox/docs-checkbox.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; 3 | import { RouterModule, Routes } from '@angular/router'; 4 | 5 | import { DocsCheckboxComponent } from './docs-checkbox.component'; 6 | 7 | const routes: Routes = [{ path: '', component: DocsCheckboxComponent }]; 8 | 9 | @NgModule({ 10 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 11 | imports: [RouterModule.forChild(routes), CommonModule], 12 | declarations: [DocsCheckboxComponent] 13 | }) 14 | export class DocsCheckboxModule {} 15 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-datalist/docs-datalist.component.html: -------------------------------------------------------------------------------- 1 |

Datalist

2 | 3 | import 'lithium-ui/datalist' 4 | 5 |

6 | The li-datalist component provides basic styles as well as accessibility and id attribute association for the 7 | input and datalist. 8 |

9 | 10 | 11 | Example 12 | API 13 | Theme 14 | 15 | 16 |

Example

17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |

Value: {{ form.controls.search.value }}

34 |
35 |
36 | 37 | 38 |
39 | 40 |

API

41 | 42 |
43 |
44 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-datalist/docs-datalist.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { FormBuilder, FormGroup } from '@angular/forms'; 3 | 4 | @Component({ 5 | selector: 'app-docs-datalist', 6 | templateUrl: './docs-datalist.component.html' 7 | }) 8 | export class DocsDatalistComponent { 9 | form: FormGroup; 10 | 11 | codeExampleImport = ` 12 | import 'lithium-ui/datalist'; 13 | `; 14 | 15 | codeExampleHtml = ` 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | `; 29 | 30 | constructor(private formBuilder: FormBuilder) { 31 | this.form = this.formBuilder.group({ 32 | search: [''] 33 | }); 34 | } 35 | 36 | submit() { 37 | console.log(this.form.value); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-datalist/docs-datalist.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; 3 | import { RouterModule, Routes } from '@angular/router'; 4 | 5 | import { SharedModule } from '../../common/shared/shared.module'; 6 | import { DocsDatalistComponent } from './docs-datalist.component'; 7 | 8 | const routes: Routes = [{ path: '', component: DocsDatalistComponent }]; 9 | 10 | @NgModule({ 11 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 12 | imports: [RouterModule.forChild(routes), CommonModule, SharedModule], 13 | declarations: [DocsDatalistComponent] 14 | }) 15 | export class DocsDatalistModule {} 16 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-datepicker/docs-datepicker.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { FormControl } from '@angular/forms'; 3 | import { addDays, format, subDays } from 'date-fns'; 4 | 5 | @Component({ 6 | selector: 'app-docs-datepicker', 7 | templateUrl: './docs-datepicker.component.html' 8 | }) 9 | export class DocsDatepickerComponent { 10 | private today = new Date('December 15, 2019'); 11 | defaultDate = new FormControl(format(this.today, 'yyyy-MM-dd')); 12 | 13 | inlineDateValue = format(this.today, 'yyyy-MM-dd'); // set by (change) event which Angular forms doesn't use but rather (input). 14 | inlineDate = new FormControl(this.inlineDateValue); 15 | 16 | minMaxDate = new FormControl(format(this.today, 'yyyy-MM-dd')); 17 | minDate = format(subDays(this.today, 3), 'yyyy-MM-dd'); 18 | maxDate = format(addDays(this.today, 3), 'yyyy-MM-dd'); 19 | 20 | startDate = new FormControl(format(subDays(this.today, 3), 'yyyy-MM-dd')); 21 | endDate = new FormControl(format(addDays(this.today, 3), 'yyyy-MM-dd')); 22 | 23 | codeExampleImport = ` 24 | import 'lithium-ui/datepicker'; 25 | `; 26 | 27 | codeExampleHtml = ` 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | `; 51 | } 52 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-datepicker/docs-datepicker.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; 3 | import { RouterModule, Routes } from '@angular/router'; 4 | 5 | import { SharedModule } from '../../common/shared/shared.module'; 6 | import { DocsDatepickerComponent } from './docs-datepicker.component'; 7 | 8 | const routes: Routes = [{ path: '', component: DocsDatepickerComponent }]; 9 | 10 | @NgModule({ 11 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 12 | imports: [RouterModule.forChild(routes), CommonModule, SharedModule], 13 | declarations: [DocsDatepickerComponent] 14 | }) 15 | export class DocsDatepickerModule {} 16 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-forms/docs-forms.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; 3 | import { RouterModule, Routes } from '@angular/router'; 4 | 5 | import { SharedModule } from '../../common/shared/shared.module'; 6 | import { DocsFormsComponent } from './docs-forms.component'; 7 | 8 | const routes: Routes = [{ path: '', component: DocsFormsComponent }]; 9 | 10 | @NgModule({ 11 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 12 | imports: [RouterModule.forChild(routes), CommonModule, SharedModule], 13 | declarations: [DocsFormsComponent] 14 | }) 15 | export class DocsFormsModule {} 16 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-home/docs-home.component.html: -------------------------------------------------------------------------------- 1 |

Getting Started

2 | 3 | 4 |

5 | This library is a experimental project to test Web Component features and architecture. Use at your own risk! 6 |

7 |
8 | 9 |

10 | To get started using lithium components install via npm. Install required peer dependencies. 11 |

12 | 13 | 14 | 15 |

16 | Then to use a component import it into your JavaScript. 17 |

18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-home/docs-home.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-docs-home', 5 | templateUrl: './docs-home.component.html' 6 | }) 7 | export class DocsHomeComponent { 8 | showDropdown = false; 9 | codeExample = ` 10 | npm install lithium-ui --save 11 | `; 12 | codeExample2 = ` 13 | import 'lithium-ui/modal'; 14 | `; 15 | codeExample3 = ` 16 | 17 | Hello World 18 | 19 | `; 20 | } 21 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-i18n/docs-i18n.component.html: -------------------------------------------------------------------------------- 1 |

Internationalization (i18n)

2 | 3 |

4 | To change the underlying language within components use the IntlService. This is important for the underlying internal 5 | accessibility and aria labels. 6 |

7 | 8 | 9 | 10 |
11 | 12 |

Registry Values

13 |
{{ IntlService.registry | json }}
15 |     
16 |
17 |
18 | English 19 | French 20 |
21 |
22 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-i18n/docs-i18n.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | import { englishRegistry, IntlService } from 'lithium-ui'; 4 | 5 | @Component({ 6 | selector: 'app-docs-i18n', 7 | templateUrl: './docs-i18n.component.html' 8 | }) 9 | export class DocsI18nComponent { 10 | IntlService = IntlService; 11 | 12 | codeExample = ` 13 | import { IntlService } from 'lithium-ui'; 14 | 15 | IntlService.registry.open // 'Open' 16 | 17 | // set once at app startup 18 | IntlService.setRegistry({ 19 | open: 'Ouvrir', 20 | close: 'Fermer', 21 | menu: 'Menu', 22 | error: 'Erreur' 23 | }); 24 | 25 | IntlService.registry.open; // 'Ouvrir' 26 | `; 27 | 28 | setEnglish() { 29 | IntlService.setRegistry(englishRegistry); 30 | } 31 | 32 | setFrench() { 33 | IntlService.setRegistry({ 34 | open: 'Ouvrir', 35 | close: 'Fermer', 36 | menu: 'Menu', 37 | error: 'Erreur', 38 | warning: 'Avertissement', 39 | success: 'Succès', 40 | info: 'Information', 41 | loading: 'Chargement', 42 | previousMonth: '', 43 | nextMonth: '' 44 | }); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-i18n/docs-i18n.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; 3 | import { RouterModule, Routes } from '@angular/router'; 4 | 5 | import { DocsI18nComponent } from './docs-i18n.component'; 6 | 7 | const routes: Routes = [{ path: '', component: DocsI18nComponent }]; 8 | 9 | @NgModule({ 10 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 11 | imports: [RouterModule.forChild(routes), CommonModule], 12 | declarations: [DocsI18nComponent] 13 | }) 14 | export class DocsI18nModule {} 15 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-icons/docs-icons.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | import 'lithium-ui/icon'; 4 | import { closeIcon, IconService, menuIcon } from 'lithium-ui/icon-shapes'; 5 | IconService.addIcons(closeIcon, menuIcon); 6 | 7 | @Component({ 8 | selector: 'app-docs-icons', 9 | templateUrl: './docs-icons.component.html' 10 | }) 11 | export class DocsIconsComponent { 12 | codeExample = ` 13 | import 'lithium-ui/icon'; 14 | import { IconService, closeIcon, menuIcon } from 'lithium-ui/icon-shapes'; 15 | IconService.addIcons(closeIcon, menuIcon); 16 | `; 17 | 18 | codeExample2 = ` 19 | 20 | 21 | `; 22 | 23 | codeExample3 = ` 24 | import 'lithium-ui/icon'; 25 | import { IconService, allIconsCollection } from 'lithium-ui/icon-shapes'; 26 | IconService.addIconCollections(allIconsCollection); 27 | `; 28 | 29 | codeExample4 = ` 30 | import 'lithium-ui/icon'; 31 | import { IconService } from 'lithium-ui/icon-shapes'; 32 | 33 | const customIcon = { 34 | name: 'circle', 35 | svg: '' 36 | }; 37 | 38 | IconService.addIcons(customIcon); 39 | `; 40 | 41 | codeExample5 = ` 42 | 43 | `; 44 | 45 | constructor() { 46 | const customIcon = { 47 | name: 'circle', 48 | svg: `` 49 | }; 50 | 51 | IconService.addIcons(customIcon); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-icons/docs-icons.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; 3 | import { RouterModule, Routes } from '@angular/router'; 4 | 5 | import { DocsIconsComponent } from './docs-icons.component'; 6 | 7 | const routes: Routes = [{ path: '', component: DocsIconsComponent }]; 8 | 9 | @NgModule({ 10 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 11 | imports: [RouterModule.forChild(routes), CommonModule], 12 | declarations: [DocsIconsComponent] 13 | }) 14 | export class DocsIconsModule {} 15 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-input/docs-input.component.html: -------------------------------------------------------------------------------- 1 |

Input

2 | 3 | import 'lithium-ui/input' 4 | 5 |

6 | The li-input component provides default styles and utilities to input type elements. This includes built in accessibility 7 | (a11y) with proper labeling and error messages. 8 |

9 | 10 | 11 | Example 12 | API 13 | Theme 14 | 15 | 16 |

Example

17 | 18 | 19 | 20 | 21 | Must be a active account. 22 | Invalid 23 | 24 | 25 | 26 | 27 | 28 | Must be 18 years or older. 29 | Required 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
40 | 41 |

API

42 | 43 |
44 |
45 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-input/docs-input.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-docs-input', 5 | templateUrl: './docs-input.component.html' 6 | }) 7 | export class DocsInputComponent { 8 | codeExampleImport = ` 9 | import 'lithium-ui/input'; 10 | `; 11 | 12 | codeExampleHtml = ` 13 | 14 | 15 | 16 | Must be a active account. 17 | Invalid 18 | 19 | 20 | 21 | 22 | 23 | Must be 18 years or older. 24 | Required 25 | 26 | 27 | 28 | 29 | 30 | 31 | `; 32 | } 33 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-input/docs-input.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; 3 | import { RouterModule, Routes } from '@angular/router'; 4 | 5 | import { DocsInputComponent } from './docs-input.component'; 6 | 7 | const routes: Routes = [{ path: '', component: DocsInputComponent }]; 8 | 9 | @NgModule({ 10 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 11 | imports: [RouterModule.forChild(routes), CommonModule], 12 | declarations: [DocsInputComponent] 13 | }) 14 | export class DocsInputModule {} 15 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-message/docs-message.component.html: -------------------------------------------------------------------------------- 1 |

Message

2 | 3 | import 'lithium-ui/message' 4 | 5 |

6 | The message component is for surfacing important information to the user that does not need to interrupt current actions. 7 |

8 | 9 | 10 | Example 11 | API 12 | Theme 13 | 14 | 15 |

Example

16 | 17 | Default Message 18 | Success Message 19 | Warning Message 20 | Error Message 21 | 22 | 23 | 24 |
25 | 26 |

API

27 | 28 |
29 |
30 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-message/docs-message.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-docs-message', 5 | templateUrl: './docs-message.component.html' 6 | }) 7 | export class DocsMessageComponent implements OnInit { 8 | codeExampleImport = ` 9 | import 'lithium-ui/message'; 10 | `; 11 | 12 | codeExampleHtml = ` 13 | Default Message 14 | Success Message 15 | Warning Message 16 | Error Message 17 | `; 18 | constructor() {} 19 | 20 | ngOnInit() {} 21 | 22 | log(e: any) { 23 | console.log(e); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-message/docs-message.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; 3 | import { RouterModule, Routes } from '@angular/router'; 4 | 5 | import { DocsMessageComponent } from './docs-message.component'; 6 | 7 | const routes: Routes = [{ path: '', component: DocsMessageComponent }]; 8 | 9 | @NgModule({ 10 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 11 | imports: [RouterModule.forChild(routes), CommonModule], 12 | declarations: [DocsMessageComponent] 13 | }) 14 | export class DocsMessageModule {} 15 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-modal/docs-modal.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { FormControl } from '@angular/forms'; 3 | 4 | @Component({ 5 | selector: 'app-docs-modal', 6 | templateUrl: './docs-modal.component.html' 7 | }) 8 | export class DocsModalComponent implements OnInit { 9 | openModal = false; 10 | formsModal = false; 11 | largeModal = false; 12 | input = new FormControl('Hello World Content'); 13 | 14 | codeExampleImport = ` 15 | import 'lithium-ui/modal'; 16 | `; 17 | 18 | codeExampleHtml = ` 19 | 20 | 21 | Hello World 22 | 23 | 24 | 25 | 26 | 27 |

Hello World Header

28 |
29 | 30 |

Hello World

31 |
32 | 33 | Hello World Actions 34 | 35 |
36 | `; 37 | 38 | constructor() {} 39 | 40 | ngOnInit() {} 41 | } 42 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-modal/docs-modal.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; 3 | import { RouterModule, Routes } from '@angular/router'; 4 | 5 | import { DocsModalComponent } from './docs-modal.component'; 6 | 7 | const routes: Routes = [{ path: '', component: DocsModalComponent }]; 8 | 9 | @NgModule({ 10 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 11 | imports: [RouterModule.forChild(routes), CommonModule], 12 | declarations: [DocsModalComponent] 13 | }) 14 | export class DocsModalModule {} 15 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-nav-bar/docs-nav-bar.component.html: -------------------------------------------------------------------------------- 1 |

Nav Bar

2 | 3 | import 'lithium-ui/nav-bar' 4 | 5 |

The li-nav-bar is a standard heading bar navigation.

6 | 7 | 8 | Example 9 | API 10 | Theme 11 | 12 | 13 |

Example

14 | 15 | 16 | Lithium 17 | Docs 18 | About 19 | Support 20 | 21 | 22 |
23 | 24 | 25 | 26 |
27 | 28 |

API

29 | 30 |
31 |
32 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-nav-bar/docs-nav-bar.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-docs-nav-bar', 5 | templateUrl: './docs-nav-bar.component.html' 6 | }) 7 | export class DocsNavBarComponent { 8 | codeExampleImport = ` 9 | import 'lithium-ui/nav-bar'; 10 | `; 11 | 12 | codeExampleHtml = ` 13 | 14 | Lithium 15 | Docs 16 | About 17 | Support 18 | 19 | `; 20 | } 21 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-nav-bar/docs-nav-bar.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; 3 | import { RouterModule, Routes } from '@angular/router'; 4 | 5 | import { DocsNavBarComponent } from './docs-nav-bar.component'; 6 | 7 | const routes: Routes = [{ path: '', component: DocsNavBarComponent }]; 8 | 9 | @NgModule({ 10 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 11 | imports: [RouterModule.forChild(routes), CommonModule], 12 | declarations: [DocsNavBarComponent] 13 | }) 14 | export class DocsNavBarModule {} 15 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-progress/docs-progress.component.html: -------------------------------------------------------------------------------- 1 |

Progress

2 | 3 | import 'lithium-ui/progress' 4 | 5 |

The li-progress is a simple component to give the user notice of a process being run with a estimate of completion.

6 | 7 | 8 | Example 9 | API 10 | Theme 11 | 12 | 13 |

Example

14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 |

API

28 | 29 |
30 |
31 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-progress/docs-progress.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-docs-progress', 5 | templateUrl: './docs-progress.component.html' 6 | }) 7 | export class DocsProgressBarComponent { 8 | codeExampleHtml = ` 9 | 10 | 11 | 12 | 13 | 14 | `; 15 | 16 | componentExample = { 17 | angular: ` 18 | 19 | 20 | 21 | 22 | 23 | `, 24 | vue: ` 25 | 26 | 27 | 28 | 29 | 30 | `, 31 | javascript: ` 32 | 33 | 34 | 35 | 36 | 37 | 38 | 42 | ` 43 | }; 44 | } 45 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-progress/docs-progress.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; 3 | import { RouterModule, Routes } from '@angular/router'; 4 | 5 | import { SharedModule } from '../../common/shared/shared.module'; 6 | import { DocsProgressBarComponent } from './docs-progress.component'; 7 | 8 | const routes: Routes = [{ path: '', component: DocsProgressBarComponent }]; 9 | 10 | @NgModule({ 11 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 12 | imports: [RouterModule.forChild(routes), CommonModule, SharedModule], 13 | declarations: [DocsProgressBarComponent] 14 | }) 15 | export class DocsProgressBarModule {} 16 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-radio/docs-radio.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { FormBuilder, FormGroup } from '@angular/forms'; 3 | import { Observable } from 'rxjs'; 4 | import { map, startWith } from 'rxjs/operators'; 5 | 6 | @Component({ 7 | selector: 'app-docs-radio', 8 | templateUrl: './docs-radio.component.html' 9 | }) 10 | export class DocsRadioComponent { 11 | form: FormGroup; 12 | value: Observable; 13 | 14 | codeExampleImport = ` 15 | import 'lithium-ui/radio'; 16 | `; 17 | 18 | codeExampleHtml = ` 19 | 20 | Choose a Country 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | `; 39 | 40 | constructor(private formBuilder: FormBuilder) { 41 | this.form = this.formBuilder.group({ 42 | region: ['south-america'] 43 | }); 44 | 45 | this.value = this.form.valueChanges.pipe( 46 | startWith('south-america'), 47 | map(() => this.form.value) 48 | ); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-radio/docs-radio.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; 3 | import { RouterModule, Routes } from '@angular/router'; 4 | 5 | import { SharedModule } from '../../common/shared/shared.module'; 6 | import { DocsRadioComponent } from './docs-radio.component'; 7 | 8 | const routes: Routes = [{ path: '', component: DocsRadioComponent }]; 9 | 10 | @NgModule({ 11 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 12 | imports: [RouterModule.forChild(routes), CommonModule, SharedModule], 13 | declarations: [DocsRadioComponent] 14 | }) 15 | export class DocsRadioModule {} 16 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-select/docs-select.component.html: -------------------------------------------------------------------------------- 1 |

Select

2 | 3 | import 'lithium-ui/select' 4 | 5 |

6 | The li-select component provides default styles and utilities to select elements. This includes built in accessibility (a11y) 7 | with proper labeling and error messages. 8 |

9 | 10 | 11 | Example 12 | API 13 | Theme 14 | 15 | 16 |

Example

17 | 18 | 19 | 20 | 25 | 26 | 27 | 28 | 29 | 34 | At least one must be selected. 35 | 36 | 37 | 38 | 39 | 44 | 45 | 46 | 47 | 48 |
49 | 50 |

API

51 | 52 |
53 |
54 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-select/docs-select.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-docs-select', 5 | templateUrl: './docs-select.component.html' 6 | }) 7 | export class DocsSelectComponent { 8 | codeExampleImport = ` 9 | import 'lithium-ui/select'; 10 | `; 11 | 12 | codeExampleHtml = ` 13 | 14 | 15 | 20 | 21 | 22 | 23 | 24 | 29 | At least one must be selected. 30 | 31 | 32 | 33 | 34 | 39 | 40 | `; 41 | } 42 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-select/docs-select.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; 3 | import { RouterModule, Routes } from '@angular/router'; 4 | 5 | import { DocsSelectComponent } from './docs-select.component'; 6 | 7 | const routes: Routes = [{ path: '', component: DocsSelectComponent }]; 8 | 9 | @NgModule({ 10 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 11 | imports: [RouterModule.forChild(routes), CommonModule], 12 | declarations: [DocsSelectComponent] 13 | }) 14 | export class DocsSelectModule {} 15 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-side-nav/docs-side-nav.component.html: -------------------------------------------------------------------------------- 1 |

Side Nav

2 | 3 | import 'lithium-ui/side-nav' 4 | 5 |

The li-side-nav component is a simple mobile friendly nav drawer that can be used on desktop as well.

6 | 7 | 8 | Example 9 | API 10 | Theme 11 | 12 | 13 |

Example

14 | Toggle Side Nav 15 | 16 | 17 | Getting Started 18 | Modal 19 | 20 | 21 | 22 | 23 |
24 | 25 |

API

26 | 27 |
28 |
29 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-side-nav/docs-side-nav.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-docs-side-nav', 5 | templateUrl: './docs-side-nav.component.html' 6 | }) 7 | export class DocsSideNavComponent implements OnInit { 8 | open = false; 9 | 10 | codeExampleImport = ` 11 | import 'lithium-ui/side-nav'; 12 | `; 13 | 14 | codeExampleHtml = ` 15 | 16 | Getting Started 17 | Modal 18 | 19 | `; 20 | 21 | constructor() {} 22 | 23 | ngOnInit() {} 24 | } 25 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-side-nav/docs-side-nav.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; 3 | import { RouterModule, Routes } from '@angular/router'; 4 | 5 | import { DocsSideNavComponent } from './docs-side-nav.component'; 6 | 7 | const routes: Routes = [{ path: '', component: DocsSideNavComponent }]; 8 | 9 | @NgModule({ 10 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 11 | imports: [RouterModule.forChild(routes), CommonModule], 12 | declarations: [DocsSideNavComponent] 13 | }) 14 | export class DocsSideNavModule {} 15 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-tabs/docs-tabs.component.html: -------------------------------------------------------------------------------- 1 |

Tabs

2 | 3 | import 'lithium-ui/tabs' 4 | 5 |

6 | Tabs are useful for grouping closely related content or tasks together. If tabs overflow on smaller devices the tab navigation will 7 | overflow as a horizontal scroll. 8 |

9 | 10 | 11 | Example 12 | API 13 | 17 | 18 | 19 |

Example

20 | 21 | 22 |
23 | 24 |

API

25 | 26 |
27 | 39 |
40 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-tabs/docs-tabs.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-docs-tabs', 5 | templateUrl: './docs-tabs.component.html' 6 | }) 7 | export class DocsTabsComponent { 8 | codeExampleImport = ` 9 | import 'lithium-ui/tabs'; 10 | `; 11 | 12 | codeExampleTypes = ` 13 | 14 | Tab 1 15 | Tab 2 16 | Tab 3 17 | 18 |

Tab 1

19 |
20 | 21 |

Tab 2

22 |
23 | 24 |

Tab 3

25 |
26 |
27 | `; 28 | } 29 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-tabs/docs-tabs.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; 3 | import { RouterModule, Routes } from '@angular/router'; 4 | 5 | import { DocsTabsComponent } from './docs-tabs.component'; 6 | 7 | const routes: Routes = [{ path: '', component: DocsTabsComponent }]; 8 | 9 | @NgModule({ 10 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 11 | imports: [RouterModule.forChild(routes), CommonModule], 12 | declarations: [DocsTabsComponent] 13 | }) 14 | export class DocsTabsModule {} 15 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-textarea/docs-textarea.component.html: -------------------------------------------------------------------------------- 1 |

Textarea

2 | 3 | import 'lithium-ui/textarea' 4 | 5 |

6 | The li-textarea component provides default styles and utilities to textarea elements. This includes built in accessibility 7 | (a11y) with proper labeling and error messages. 8 |

9 | 10 | 11 | Example 12 | API 13 | Theme 14 | 15 | 16 |

Example

17 | 18 | 19 | 20 | 21 | Maximum of 100 characters. 22 | Required 23 | 24 | 25 | 26 | 27 | 28 | Maximum of 100 characters. 29 | Required 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
40 | 41 |

API

42 | 43 |
44 |
45 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-textarea/docs-textarea.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-docs-textarea', 5 | templateUrl: './docs-textarea.component.html' 6 | }) 7 | export class DocsTextareaComponent { 8 | codeExampleImport = ` 9 | import 'lithium-ui/textarea'; 10 | `; 11 | 12 | codeExampleHtml = ` 13 | 14 | 15 | 16 | Maximum of 100 characters. 17 | Required 18 | 19 | 20 | 21 | 22 | 23 | Maximum of 100 characters. 24 | Required 25 | 26 | `; 27 | } 28 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-textarea/docs-textarea.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; 3 | import { RouterModule, Routes } from '@angular/router'; 4 | 5 | import { DocsTextareaComponent } from './docs-textarea.component'; 6 | 7 | const routes: Routes = [{ path: '', component: DocsTextareaComponent }]; 8 | 9 | @NgModule({ 10 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 11 | imports: [RouterModule.forChild(routes), CommonModule], 12 | declarations: [DocsTextareaComponent] 13 | }) 14 | export class DocsTextareaModule {} 15 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-themes/docs-themes.component.html: -------------------------------------------------------------------------------- 1 |

Themes

2 | 3 |

4 | Lithium uses CSS Custom Properties to easily theme and style components. Using CSS Custom Properties allows components to be dynamically 5 | changed in the browser. 6 |

7 | 8 | Toggle Theme 9 | 10 |

Component Themes

11 | 12 |

13 | View the API reference docs to see available CSS Custom Properties specific to each component. 14 |

15 | 16 | 17 | 18 |

Global Settings

19 | 20 |

21 | Each component has its own set of custom CSS properties for themes. There are global variables available that can adjust all lithium 22 | components at once. 23 |

24 | 25 | 26 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-themes/docs-themes.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | import { ThemeService } from '../../common/core/services/theme.service'; 4 | 5 | @Component({ 6 | selector: 'app-docs-themes', 7 | templateUrl: './docs-themes.component.html' 8 | }) 9 | export class DocsThemesComponent implements OnInit { 10 | codeExample = ` 11 | li-card { 12 | --background: #ccc; 13 | --border-color: #2d2d2d; 14 | } 15 | `; 16 | 17 | globalVarsExample = ` 18 | /* Default global variables and values */ 19 | :root { 20 | /* default margin bottom spacing for lithium components */ 21 | --li-global-spacing-margin-bottom: 2.4em; 22 | --li-global-spacing-margin-bottom-small: 1.2em; 23 | --li-global-spacing-margin-bottom-large: 3.6em; 24 | 25 | /* Global baseline font size for lithium components */ 26 | --li-global-base-font-size: 10px; 27 | } 28 | `; 29 | 30 | constructor(private themeService: ThemeService) {} 31 | 32 | ngOnInit() {} 33 | 34 | toggleTheme() { 35 | this.themeService.toggleTheme(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs-themes/docs-themes.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; 3 | import { RouterModule, Routes } from '@angular/router'; 4 | 5 | import { DocsThemesComponent } from './docs-themes.component'; 6 | 7 | const routes: Routes = [{ path: '', component: DocsThemesComponent }]; 8 | 9 | @NgModule({ 10 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 11 | imports: [RouterModule.forChild(routes), CommonModule], 12 | declarations: [DocsThemesComponent] 13 | }) 14 | export class DocsThemesModule {} 15 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |
5 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs.component.scss: -------------------------------------------------------------------------------- 1 | @import './../../styles//variables'; 2 | 3 | .docs-content { 4 | padding: 6.4rem 1.2rem; 5 | 6 | @media (min-width: $nav-breakpoint) { 7 | padding: 8.3rem 2.4rem 2.4rem 31.5rem; 8 | } 9 | 10 | @media (min-width: $book-ad-breakpoint) { 11 | max-width: 114rem; 12 | } 13 | 14 | @media (min-width: 1600px) { 15 | max-width: 130rem; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | import { fadeAnimation } from '../common/animations'; 4 | 5 | @Component({ 6 | selector: 'app-docs', 7 | templateUrl: './docs.component.html', 8 | styleUrls: ['./docs.component.scss'], 9 | animations: [fadeAnimation] 10 | }) 11 | export class DocsComponent {} 12 | -------------------------------------------------------------------------------- /projects/docs/src/app/docs/docs.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; 3 | import { SharedModule } from '../common/shared/shared.module'; 4 | import { DocsHomeComponent } from './docs-home/docs-home.component'; 5 | import { DocsRoutingModule } from './docs-routing.module'; 6 | import { DocsComponent } from './docs.component'; 7 | 8 | @NgModule({ 9 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 10 | declarations: [DocsComponent, DocsHomeComponent], 11 | imports: [CommonModule, SharedModule, DocsRoutingModule] 12 | }) 13 | export class DocsModule {} 14 | -------------------------------------------------------------------------------- /projects/docs/src/app/home/home.component.scss: -------------------------------------------------------------------------------- 1 | @import './../../styles//variables'; 2 | 3 | [bp='container'] { 4 | padding: 2.4rem 1.2rem; 5 | 6 | @media (min-width: $nav-breakpoint) { 7 | padding: 2.4rem; 8 | } 9 | } 10 | 11 | .hero { 12 | padding: 4.5rem 1.4rem; 13 | background-color: var(--hero-background-color); 14 | 15 | @media (min-width: 720px) { 16 | margin: 0 -3rem; 17 | } 18 | } 19 | 20 | .logo { 21 | margin: 5rem auto 0 auto; 22 | font-size: 90px; 23 | } 24 | 25 | h1 { 26 | font-size: 4.5rem; 27 | 28 | .version { 29 | font-size: 1.4rem; 30 | } 31 | } 32 | 33 | h2 { 34 | font-size: 2.4rem; 35 | } 36 | 37 | h3 { 38 | font-size: 1.8rem; 39 | line-height: 2.8rem; 40 | margin: 3rem 0; 41 | } 42 | 43 | .images { 44 | display: block; 45 | max-width: 40rem; 46 | margin: 4rem auto 3.5rem auto; 47 | 48 | img { 49 | display: inline-block; 50 | width: 6rem; 51 | margin-right: 3rem; 52 | } 53 | 54 | .angular, 55 | .javascript { 56 | width: 5rem; 57 | } 58 | 59 | .vue { 60 | margin-right: 0; 61 | } 62 | 63 | .javascript { 64 | margin-right: 4rem; 65 | } 66 | } 67 | 68 | hr { 69 | height: 2px; 70 | width: 100%; 71 | border: 0; 72 | background: linear-gradient(to right, var(--logo-color-one) 0%, var(--logo-color-two) 100%); 73 | margin-top: 4rem; 74 | top: 17px; 75 | position: absolute; 76 | left: 0; 77 | right: 0; 78 | } 79 | 80 | .hero-2 { 81 | padding-top: 3rem; 82 | 83 | h2, 84 | h3 { 85 | margin-bottom: 1rem; 86 | } 87 | 88 | @media (min-width: $nav-breakpoint) { 89 | padding-top: 6rem; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /projects/docs/src/app/home/home.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { environment } from '../../environments/environment'; 3 | 4 | @Component({ 5 | selector: 'app-home', 6 | templateUrl: './home.component.html', 7 | styleUrls: ['./home.component.scss'] 8 | }) 9 | export class HomeComponent implements OnInit { 10 | version = environment.version; 11 | 12 | codeExample = ` 13 | import 'lithium-ui/modal'; 14 | 15 | const modal = document.querySelector('li-modal'); 16 | modal.toggle(); 17 | `; 18 | codeExample2 = ` 19 | 20 | Hello World 21 | 22 | `; 23 | 24 | constructor() {} 25 | 26 | ngOnInit() {} 27 | } 28 | -------------------------------------------------------------------------------- /projects/docs/src/app/pricing/pricing-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | 4 | import { PricingComponent } from './pricing.component'; 5 | 6 | const routes: Routes = [{ path: '', component: PricingComponent }]; 7 | 8 | @NgModule({ 9 | imports: [RouterModule.forChild(routes)], 10 | exports: [RouterModule] 11 | }) 12 | export class PricingRoutingModule {} 13 | -------------------------------------------------------------------------------- /projects/docs/src/app/pricing/pricing.component.html: -------------------------------------------------------------------------------- 1 |

Pricing for Pro Components Coming Soon.

2 | -------------------------------------------------------------------------------- /projects/docs/src/app/pricing/pricing.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-pricing', 5 | templateUrl: './pricing.component.html' 6 | }) 7 | export class PricingComponent implements OnInit { 8 | constructor() {} 9 | 10 | ngOnInit() {} 11 | } 12 | -------------------------------------------------------------------------------- /projects/docs/src/app/pricing/pricing.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; 3 | 4 | import { PricingRoutingModule } from './pricing-routing.module'; 5 | import { PricingComponent } from './pricing.component'; 6 | 7 | @NgModule({ 8 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 9 | imports: [CommonModule, PricingRoutingModule], 10 | declarations: [PricingComponent] 11 | }) 12 | export class PricingModule {} 13 | -------------------------------------------------------------------------------- /projects/docs/src/app/support/support-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | 4 | import { SupportComponent } from './support.component'; 5 | 6 | const routes: Routes = [{ path: '', component: SupportComponent }]; 7 | 8 | @NgModule({ 9 | imports: [RouterModule.forChild(routes)], 10 | exports: [RouterModule] 11 | }) 12 | export class SupportRoutingModule {} 13 | -------------------------------------------------------------------------------- /projects/docs/src/app/support/support.component.html: -------------------------------------------------------------------------------- 1 |

Support

2 | 3 | test 4 | -------------------------------------------------------------------------------- /projects/docs/src/app/support/support.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-support', 5 | templateUrl: './support.component.html' 6 | }) 7 | export class SupportComponent implements OnInit { 8 | constructor() {} 9 | 10 | ngOnInit() {} 11 | } 12 | -------------------------------------------------------------------------------- /projects/docs/src/app/support/support.module.ts: -------------------------------------------------------------------------------- 1 | import { CommonModule } from '@angular/common'; 2 | import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; 3 | 4 | import { SupportRoutingModule } from './support-routing.module'; 5 | import { SupportComponent } from './support.component'; 6 | 7 | @NgModule({ 8 | schemas: [CUSTOM_ELEMENTS_SCHEMA], 9 | imports: [CommonModule, SupportRoutingModule], 10 | declarations: [SupportComponent] 11 | }) 12 | export class SupportModule {} 13 | -------------------------------------------------------------------------------- /projects/docs/src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coryrylan/lithium/4e3bca83b1fa12c4572f3fed0f90fd52b1213392/projects/docs/src/assets/.gitkeep -------------------------------------------------------------------------------- /projects/docs/src/assets/images/angular.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /projects/docs/src/assets/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coryrylan/lithium/4e3bca83b1fa12c4572f3fed0f90fd52b1213392/projects/docs/src/assets/images/icon.png -------------------------------------------------------------------------------- /projects/docs/src/assets/images/icons/icon-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coryrylan/lithium/4e3bca83b1fa12c4572f3fed0f90fd52b1213392/projects/docs/src/assets/images/icons/icon-128x128.png -------------------------------------------------------------------------------- /projects/docs/src/assets/images/icons/icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coryrylan/lithium/4e3bca83b1fa12c4572f3fed0f90fd52b1213392/projects/docs/src/assets/images/icons/icon-144x144.png -------------------------------------------------------------------------------- /projects/docs/src/assets/images/icons/icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coryrylan/lithium/4e3bca83b1fa12c4572f3fed0f90fd52b1213392/projects/docs/src/assets/images/icons/icon-152x152.png -------------------------------------------------------------------------------- /projects/docs/src/assets/images/icons/icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coryrylan/lithium/4e3bca83b1fa12c4572f3fed0f90fd52b1213392/projects/docs/src/assets/images/icons/icon-192x192.png -------------------------------------------------------------------------------- /projects/docs/src/assets/images/icons/icon-384x384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coryrylan/lithium/4e3bca83b1fa12c4572f3fed0f90fd52b1213392/projects/docs/src/assets/images/icons/icon-384x384.png -------------------------------------------------------------------------------- /projects/docs/src/assets/images/icons/icon-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coryrylan/lithium/4e3bca83b1fa12c4572f3fed0f90fd52b1213392/projects/docs/src/assets/images/icons/icon-512x512.png -------------------------------------------------------------------------------- /projects/docs/src/assets/images/icons/icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coryrylan/lithium/4e3bca83b1fa12c4572f3fed0f90fd52b1213392/projects/docs/src/assets/images/icons/icon-72x72.png -------------------------------------------------------------------------------- /projects/docs/src/assets/images/icons/icon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coryrylan/lithium/4e3bca83b1fa12c4572f3fed0f90fd52b1213392/projects/docs/src/assets/images/icons/icon-96x96.png -------------------------------------------------------------------------------- /projects/docs/src/assets/images/javascript.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /projects/docs/src/assets/images/react.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /projects/docs/src/assets/images/vue.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /projects/docs/src/assets/images/web-components-and-frameworks-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coryrylan/lithium/4e3bca83b1fa12c4572f3fed0f90fd52b1213392/projects/docs/src/assets/images/web-components-and-frameworks-small.png -------------------------------------------------------------------------------- /projects/docs/src/assets/plain.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 21 | 22 | 23 | 24 | hi 25 | 26 | 27 | -------------------------------------------------------------------------------- /projects/docs/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true, 3 | version: 'v0.0.1 alpha' 4 | }; 5 | -------------------------------------------------------------------------------- /projects/docs/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false, 7 | version: 'v0.0.1 alpha' 8 | }; 9 | 10 | /* 11 | * For easier debugging in development mode, you can import the following file 12 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 13 | * 14 | * This import should be commented out in production mode because it will have a negative impact 15 | * on performance if an error is thrown. 16 | */ 17 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 18 | -------------------------------------------------------------------------------- /projects/docs/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coryrylan/lithium/4e3bca83b1fa12c4572f3fed0f90fd52b1213392/projects/docs/src/favicon.ico -------------------------------------------------------------------------------- /projects/docs/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Lithium UI 6 | 7 | 8 | 9 | 10 | 11 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /projects/docs/src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic() 12 | .bootstrapModule(AppModule) 13 | .catch(err => console.error(err)); 14 | -------------------------------------------------------------------------------- /projects/docs/src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Lithium UI", 3 | "short_name": "Lithium UI", 4 | "theme_color": "#007dff", 5 | "background_color": "#007dff", 6 | "display": "standalone", 7 | "Scope": "/", 8 | "start_url": "/", 9 | "icons": [ 10 | { 11 | "src": "assets/images/icons/icon-72x72.png", 12 | "sizes": "72x72", 13 | "type": "image/png" 14 | }, 15 | { 16 | "src": "assets/images/icons/icon-96x96.png", 17 | "sizes": "96x96", 18 | "type": "image/png" 19 | }, 20 | { 21 | "src": "assets/images/icons/icon-128x128.png", 22 | "sizes": "128x128", 23 | "type": "image/png" 24 | }, 25 | { 26 | "src": "assets/images/icons/icon-144x144.png", 27 | "sizes": "144x144", 28 | "type": "image/png" 29 | }, 30 | { 31 | "src": "assets/images/icons/icon-152x152.png", 32 | "sizes": "152x152", 33 | "type": "image/png" 34 | }, 35 | { 36 | "src": "assets/images/icons/icon-192x192.png", 37 | "sizes": "192x192", 38 | "type": "image/png" 39 | }, 40 | { 41 | "src": "assets/images/icons/icon-384x384.png", 42 | "sizes": "384x384", 43 | "type": "image/png" 44 | }, 45 | { 46 | "src": "assets/images/icons/icon-512x512.png", 47 | "sizes": "512x512", 48 | "type": "image/png" 49 | } 50 | ], 51 | "splash_pages": null 52 | } -------------------------------------------------------------------------------- /projects/docs/src/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Sitemap: https://lithiumui.dev/sitemap.xml 3 | Disallow: -------------------------------------------------------------------------------- /projects/docs/src/sitemap.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | https://lithiumui.dev 4 | 5 | 6 | https://lithiumui.dev/support 7 | 8 | 9 | https://lithiumui.dev/api 10 | 11 | 12 | https://lithiumui.dev/docs 13 | 14 | 15 | https://lithiumui.dev/docs/themes 16 | 17 | 18 | https://lithiumui.dev/docs/internationalization 19 | 20 | 21 | https://lithiumui.dev/docs/icons 22 | 23 | 24 | https://lithiumui.dev/docs/button 25 | 26 | 27 | https://lithiumui.dev/docs/card 28 | 29 | 30 | https://lithiumui.dev/docs/checkbox 31 | 32 | 33 | https://lithiumui.dev/docs/forms 34 | 35 | 36 | https://lithiumui.dev/docs/input 37 | 38 | 39 | https://lithiumui.dev/docs/message 40 | 41 | 42 | https://lithiumui.dev/docs/modal 43 | 44 | 45 | https://lithiumui.dev/docs/radio 46 | 47 | 48 | https://lithiumui.dev/docs/side-nav 49 | 50 | 51 | https://lithiumui.dev/docs/nav-bar 52 | 53 | 54 | https://lithiumui.dev/docs/select 55 | 56 | 57 | https://lithiumui.dev/docs/tabs 58 | 59 | 60 | https://lithiumui.dev/docs/textarea 61 | 62 | 63 | https://lithiumui.dev/docs/progress 64 | 65 | -------------------------------------------------------------------------------- /projects/docs/src/styles.scss: -------------------------------------------------------------------------------- 1 | @import '~normalize.css/normalize'; 2 | @import '~blueprint-css/src/blueprint'; 3 | @import './styles/variables'; 4 | @import './styles/theme'; 5 | @import './styles/typography'; 6 | @import './styles/layout'; 7 | @import './styles/logo'; 8 | -------------------------------------------------------------------------------- /projects/docs/src/styles/_layout.scss: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: var(--global-background-color); 3 | } 4 | 5 | .layout-page main { 6 | @media (min-width: $md-breakpoint) { 7 | padding: 5.8rem 3rem 6rem 3rem; 8 | } 9 | } 10 | 11 | li-side-nav { 12 | @media (min-width: $lg-breakpoint) { 13 | --padding: 6rem 0 0 0; 14 | } 15 | } 16 | 17 | router-outlet ~ * { 18 | display: block; 19 | } 20 | 21 | [bp] > li-card { 22 | margin-bottom: 0; 23 | } 24 | 25 | .theme-btn { 26 | background-color: var(--global-color-gray-400); 27 | width: 2rem; 28 | height: 2rem; 29 | border-radius: 50%; 30 | margin-left: 1rem; 31 | } 32 | 33 | .dark-theme { 34 | .theme-btn { 35 | background-color: var(--global-color-white-100); 36 | } 37 | } 38 | 39 | .layout-page .docs-nav { 40 | @media (min-width: 1024px) { 41 | display: none !important; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /projects/docs/src/styles/_logo.scss: -------------------------------------------------------------------------------- 1 | .logo { 2 | --border-width: 4px; 3 | --inner-background: #f7f7f7; 4 | font-size: 58px; 5 | padding: 0.15em; 6 | width: 1.8em; 7 | height: 1.8em; 8 | text-align: center; 9 | vertical-align: middle; 10 | background-clip: padding-box; 11 | position: relative; 12 | background: linear-gradient(to right, var(--logo-color-one) 0%, var(--logo-color-two) 100%); 13 | 14 | &:before { 15 | content: ''; 16 | position: absolute; 17 | top: var(--border-width); 18 | right: var(--border-width); 19 | bottom: var(--border-width); 20 | left: var(--border-width); 21 | z-index: 1; 22 | background-color: var(--inner-background); 23 | } 24 | 25 | .logo-inner { 26 | line-height: 1.5em; 27 | position: absolute; 28 | top: 0.1em; 29 | right: 0; 30 | bottom: 0; 31 | left: 0; 32 | z-index: 2; 33 | background: linear-gradient(to right, var(--logo-color-one) 0%, var(--logo-color-two) 100%); 34 | -webkit-background-clip: text; 35 | -webkit-text-fill-color: transparent; 36 | } 37 | } 38 | 39 | .header-logo { 40 | font-size: 18px; 41 | margin: -12px 10px -12px -8px; 42 | --border-width: 2px; 43 | --inner-background: var(--global-color-gray-100); 44 | } 45 | 46 | .dark-theme { 47 | .header-logo { 48 | --inner-background: #2d2d2d; 49 | } 50 | } 51 | 52 | .home-page .logo { 53 | --inner-background: var(--hero-background-color); 54 | } 55 | -------------------------------------------------------------------------------- /projects/docs/src/styles/_typography.scss: -------------------------------------------------------------------------------- 1 | :root { 2 | font-size: 10px; 3 | } 4 | 5 | body { 6 | font-family: 'Lato', Helvetica, Arial, 'Lucida Grande', sans-serif; 7 | color: var(--global-text-color); 8 | line-height: 1.5; 9 | } 10 | 11 | p { 12 | margin: 0 0 2.4rem 0; 13 | } 14 | 15 | a { 16 | color: var(--global-text-color); 17 | } 18 | 19 | h1, 20 | h2, 21 | h3 { 22 | margin: 0 0 2.4rem 0; 23 | line-height: 1.2; 24 | font-weight: 300; 25 | display: block; 26 | } 27 | 28 | h1 { 29 | font-size: 4.1rem; 30 | 31 | small { 32 | font-size: 1.8rem; 33 | } 34 | } 35 | 36 | .code-import { 37 | font-size: 1.6rem; 38 | padding: 0.4rem 0.6rem; 39 | margin: -0.6rem 0 1rem 0; 40 | display: inline-block; 41 | } 42 | 43 | h2 { 44 | font-size: 3.2rem; 45 | } 46 | 47 | h3 { 48 | font-size: 2.4rem; 49 | } 50 | 51 | p { 52 | font-size: 1.6rem; 53 | } 54 | 55 | code { 56 | background-color: var(--global-color-gray-100); 57 | } 58 | 59 | .dark-theme code { 60 | background-color: var(--global-color-gray-600); 61 | } 62 | 63 | blockquote { 64 | padding: 0 1rem 0 2rem; 65 | border-left: 0.5rem solid var(--global-color-gray-200); 66 | } 67 | 68 | .command { 69 | padding: 1.2rem 1.6rem; 70 | border-radius: 0.4rem; 71 | background-color: var(--global-text-color); 72 | color: var(--global-color-white-100); 73 | font-family: monospace; 74 | margin-bottom: 2.4rem; 75 | overflow-x: auto; 76 | } 77 | -------------------------------------------------------------------------------- /projects/docs/src/styles/_variables.scss: -------------------------------------------------------------------------------- 1 | $nav-breakpoint: 1024px; 2 | $book-ad-breakpoint: 1440px; 3 | $sm-breakpoint: 480px; 4 | $md-breakpoint: 720px; 5 | $lg-breakpoint: 960px; 6 | -------------------------------------------------------------------------------- /projects/docs/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import { getTestBed } from '@angular/core/testing'; 4 | import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; 5 | import 'zone.js/dist/zone-testing'; 6 | 7 | declare const require: any; 8 | 9 | // First, initialize the Angular testing environment. 10 | getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting()); 11 | // Then we find all the tests. 12 | const context = require.context('./', true, /\.spec\.ts$/); 13 | // And load the modules. 14 | context.keys().map(context); 15 | -------------------------------------------------------------------------------- /projects/docs/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../out-tsc/app" 5 | }, 6 | "files": [ 7 | "src/main.ts", 8 | "src/polyfills.ts" 9 | ], 10 | "include": [ 11 | "src/**/*.d.ts" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /projects/docs/tsconfig.prod.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.app.json", 3 | "files": [ 4 | "src/main.ts", 5 | "src/polyfills.ts" 6 | ], 7 | "include": [ 8 | "src/**/*.d.ts" 9 | ] 10 | } -------------------------------------------------------------------------------- /projects/docs/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts", 12 | "src/polyfills.ts" 13 | ], 14 | "include": [ 15 | "src/**/*.spec.ts", 16 | "src/**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /projects/docs/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tslint.json", 3 | "rules": { 4 | "directive-selector": [ 5 | true, 6 | "attribute", 7 | "app", 8 | "camelCase" 9 | ], 10 | "component-selector": [ 11 | true, 12 | "element", 13 | "app", 14 | "kebab-case" 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /projects/lithium/LICENSE-MIT.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | Copyright 2019 Crylan Software 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /projects/lithium/button/button-group.element.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | font-size: 0; 3 | } 4 | 5 | ::slotted(li-button) { 6 | border-radius: 0; 7 | margin-right: 2px !important; 8 | } 9 | 10 | ::slotted(li-button:first-child) { 11 | border-top-left-radius: var(--li-common-border-radius); 12 | border-bottom-left-radius: var(--li-common-border-radius); 13 | } 14 | 15 | ::slotted(li-button:last-child) { 16 | border-top-right-radius: var(--li-common-border-radius); 17 | border-bottom-right-radius: var(--li-common-border-radius); 18 | } 19 | 20 | ::slotted(li-button[action='secondary']) { 21 | margin-right: 0 !important; 22 | border-left: 0; 23 | border-right: 0.2em solid; 24 | } 25 | 26 | ::slotted(li-button[action='secondary']:first-child) { 27 | border-left: 0.2em solid; 28 | } 29 | -------------------------------------------------------------------------------- /projects/lithium/button/button-group.element.spec.ts: -------------------------------------------------------------------------------- 1 | import 'lithium-ui/button'; 2 | import { LithiumButtonGroup } from 'lithium-ui/button'; 3 | import { componentIsStable, createTestElement, getComponentSlotContent, removeTestElement, waitForComponent } from 'lithium-ui/test/utils'; 4 | 5 | describe('card element', () => { 6 | let testElement: HTMLElement; 7 | let component: LithiumButtonGroup; 8 | 9 | beforeEach(async () => { 10 | testElement = createTestElement(); 11 | testElement.innerHTML = ` 12 | 13 | item 1 14 | item 2 15 | 16 | `; 17 | await waitForComponent('li-button-group'); 18 | component = testElement.querySelector('li-button-group'); 19 | }); 20 | 21 | afterEach(() => { 22 | removeTestElement(testElement); 23 | }); 24 | 25 | it('should render a button group with appropriate slots', async () => { 26 | await componentIsStable(component); 27 | const slots = getComponentSlotContent(component); 28 | expect(slots.default).toContain('item 1'); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /projects/lithium/button/button-group.element.ts: -------------------------------------------------------------------------------- 1 | import { html, LitElement } from 'lit-element'; 2 | import { baseStyles, property, registerElementSafely } from 'lithium-ui/common'; 3 | import { styles } from './button-group.element.css'; 4 | 5 | /** 6 | * Button Group, group related button actions 7 | * 8 | * @noInheritDoc 9 | * @element li-button-group 10 | * @slot default - Content slot for modal body 11 | */ 12 | // @dynamic 13 | export class LithiumButtonGroup extends LitElement { 14 | /** Display group as a group of secondary actions */ 15 | @property({ type: String }) action: 'secondary' | ''; 16 | 17 | static get styles() { 18 | return [baseStyles, styles]; 19 | } 20 | 21 | protected render() { 22 | return html` 23 | 24 | `; 25 | } 26 | } 27 | 28 | declare global { 29 | interface HTMLElementTagNameMap { 30 | 'li-button-group': LithiumButtonGroup; 31 | } 32 | } 33 | 34 | registerElementSafely('li-button-group', LithiumButtonGroup); 35 | -------------------------------------------------------------------------------- /projects/lithium/button/entrypoint.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "composite": true 5 | }, 6 | "references": [{ "path": "../common/entrypoint.tsconfig.json" }, { "path": "../progress/entrypoint.tsconfig.json" }] 7 | } 8 | -------------------------------------------------------------------------------- /projects/lithium/button/index.ts: -------------------------------------------------------------------------------- 1 | export * from './button.element'; 2 | export * from './button-group.element'; 3 | -------------------------------------------------------------------------------- /projects/lithium/button/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "sideEffects": true, 3 | "main": "./index.js", 4 | "module": "./index.js", 5 | "typings": "./index.d.ts", 6 | "name": "lithium-ui/button", 7 | "type": "module" 8 | } 9 | -------------------------------------------------------------------------------- /projects/lithium/card/card-actions.element.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | display: block; 3 | display: flex; 4 | justify-content: flex-end; 5 | } 6 | 7 | ::slotted(li-button) { 8 | margin-bottom: 0 !important; 9 | } 10 | 11 | ::slotted(li-button:last-child) { 12 | margin-right: 0 !important; 13 | } 14 | -------------------------------------------------------------------------------- /projects/lithium/card/card-actions.element.ts: -------------------------------------------------------------------------------- 1 | import { html, LitElement } from 'lit-element'; 2 | import { baseStyles, registerElementSafely } from 'lithium-ui/common'; 3 | import { styles } from './card-actions.element.css'; 4 | 5 | /** 6 | * Card Actions 7 | * 8 | * @noInheritDoc 9 | * @element li-card-actions 10 | * @slot default - Content slot for card actions and buttons 11 | */ 12 | export class LithiumCardActions extends LitElement { 13 | static get styles() { 14 | return [baseStyles, styles]; 15 | } 16 | 17 | connectedCallback() { 18 | super.connectedCallback(); 19 | this.setAttribute('slot', 'actions'); 20 | } 21 | 22 | protected render() { 23 | return html` 24 | 25 | `; 26 | } 27 | } 28 | 29 | registerElementSafely('li-card-actions', LithiumCardActions); 30 | 31 | declare global { 32 | interface HTMLElementTagNameMap { 33 | 'li-card-actions': LithiumCardActions; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /projects/lithium/card/card-content.element.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coryrylan/lithium/4e3bca83b1fa12c4572f3fed0f90fd52b1213392/projects/lithium/card/card-content.element.scss -------------------------------------------------------------------------------- /projects/lithium/card/card-content.element.ts: -------------------------------------------------------------------------------- 1 | import { html, LitElement } from 'lit-element'; 2 | import { registerElementSafely } from 'lithium-ui/common'; 3 | 4 | /** 5 | * Card Content 6 | * 7 | * @noInheritDoc 8 | * @element li-card-content 9 | * @slot default - Content slot for card content 10 | */ 11 | // @dynamic 12 | export class LithiumCardContent extends LitElement { 13 | protected render() { 14 | return html` 15 | 16 | `; 17 | } 18 | } 19 | 20 | registerElementSafely('li-card-content', LithiumCardContent); 21 | 22 | declare global { 23 | interface HTMLElementTagNameMap { 24 | 'li-card-content': LithiumCardContent; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /projects/lithium/card/card-header.element.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | --border-color: var(--li-common-color-gray-200); 3 | --padding: 0 var(--li-common-padding-md) 1.6em var(--li-common-padding-md); 4 | --margin: -0.6em var(--li-common-padding-md-negative) 1.4em var(--li-common-padding-md-negative); 5 | 6 | display: block; 7 | border-bottom: 1px solid; 8 | border-color: var(--border-color); 9 | padding: var(--padding); 10 | margin: var(--margin); 11 | } 12 | 13 | ::slotted(*) { 14 | margin: 0 !important; 15 | font-size: 20px !important; 16 | } 17 | -------------------------------------------------------------------------------- /projects/lithium/card/card-header.element.ts: -------------------------------------------------------------------------------- 1 | import { html, LitElement } from 'lit-element'; 2 | import { baseStyles, registerElementSafely } from 'lithium-ui/common'; 3 | import { styles } from './card-header.element.css'; 4 | 5 | /** 6 | * Card Header 7 | * 8 | * @noInheritDoc 9 | * @element li-card-header 10 | * @slot default - Content slot for card header 11 | * @cssprop --border-color 12 | * @cssprop --padding 13 | * @cssprop --margin 14 | */ 15 | // @dynamic 16 | export class LithiumCardHeader extends LitElement { 17 | static get styles() { 18 | return [baseStyles, styles]; 19 | } 20 | 21 | connectedCallback() { 22 | super.connectedCallback(); 23 | this.setAttribute('slot', 'header'); 24 | } 25 | 26 | protected render() { 27 | return html` 28 | 29 | `; 30 | } 31 | } 32 | 33 | registerElementSafely('li-card-header', LithiumCardHeader); 34 | 35 | declare global { 36 | interface HTMLElementTagNameMap { 37 | 'li-card-header': LithiumCardHeader; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /projects/lithium/card/card.element.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | --background: var(--li-common-color-white-100); 3 | --border-color: var(--li-common-color-gray-200); 4 | --border-radius: var(--li-common-border-radius); 5 | --padding: var(--li-common-padding-md); 6 | 7 | background: var(--background); 8 | border-bottom: 0.2em solid; 9 | border-color: var(--border-color); 10 | border-radius: var(--border-radius); 11 | color: var(--color, inherit); 12 | padding: var(--padding); 13 | margin-bottom: var(--li-common-spacing-margin-bottom); 14 | display: block; 15 | position: relative; 16 | } 17 | -------------------------------------------------------------------------------- /projects/lithium/card/card.element.spec.ts: -------------------------------------------------------------------------------- 1 | import 'lithium-ui/card'; 2 | import { LithiumCard } from 'lithium-ui/card'; 3 | import { componentIsStable, createTestElement, getComponentSlotContent, removeTestElement, waitForComponent } from 'lithium-ui/test/utils'; 4 | 5 | describe('card element', () => { 6 | let testElement: HTMLElement; 7 | let component: LithiumCard; 8 | 9 | beforeEach(async () => { 10 | testElement = createTestElement(); 11 | testElement.innerHTML = ` 12 | 13 | hello header 14 | hello world 15 | hello actions 16 | 17 | `; 18 | await waitForComponent('li-card'); 19 | component = testElement.querySelector('li-card'); 20 | }); 21 | 22 | afterEach(() => { 23 | removeTestElement(testElement); 24 | }); 25 | 26 | it('should render a card with appropriate slots', async () => { 27 | await componentIsStable(component); 28 | 29 | const slots = getComponentSlotContent(component); 30 | expect(slots.default).toBe('hello world'); 31 | expect(slots.header).toBe('hello header'); 32 | expect(slots.actions).toBe('hello actions'); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /projects/lithium/card/card.element.ts: -------------------------------------------------------------------------------- 1 | import { html, LitElement } from 'lit-element'; 2 | import { baseStyles, registerElementSafely } from 'lithium-ui/common'; 3 | import { styles } from './card.element.css'; 4 | 5 | /** 6 | * Card, to organize and group related content 7 | * 8 | * @noInheritDoc 9 | * @element li-card 10 | * @slot default - Content slot for card content 11 | * @slot li-card-header - Content slot for card header 12 | * @slot li-card-content - Content slot for card content 13 | * @slot li-card-actions - Content slot for card actions 14 | * @cssprop --background 15 | * @cssprop --border-color 16 | * @cssprop --border-radius 17 | * @cssprop --color 18 | * @cssprop --padding 19 | */ 20 | // @dynamic 21 | export class LithiumCard extends LitElement { 22 | static get styles() { 23 | return [baseStyles, styles]; 24 | } 25 | 26 | render() { 27 | return html` 28 | 29 | 30 | 31 | `; 32 | } 33 | } 34 | 35 | registerElementSafely('li-card', LithiumCard); 36 | 37 | declare global { 38 | interface HTMLElementTagNameMap { 39 | 'li-card': LithiumCard; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /projects/lithium/card/entrypoint.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "composite": true 5 | }, 6 | "references": [{ "path": "../common/entrypoint.tsconfig.json" }] 7 | } 8 | -------------------------------------------------------------------------------- /projects/lithium/card/index.ts: -------------------------------------------------------------------------------- 1 | export * from './card.element'; 2 | export * from './card-actions.element'; 3 | export * from './card-content.element'; 4 | export * from './card-header.element'; 5 | -------------------------------------------------------------------------------- /projects/lithium/card/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "sideEffects": true, 3 | "main": "./index.js", 4 | "module": "./index.js", 5 | "typings": "./index.d.ts", 6 | "name": "lithium-ui/card", 7 | "type": "module" 8 | } 9 | -------------------------------------------------------------------------------- /projects/lithium/checkbox/checkbox-group.element.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | display: block; 3 | } 4 | 5 | :host([inline]) ::slotted(li-checkbox) { 6 | display: inline-block !important; 7 | } 8 | 9 | fieldset { 10 | border: 0; 11 | padding: 0; 12 | margin: 0; 13 | } 14 | 15 | ::slotted(legend) { 16 | display: block; 17 | margin-bottom: 0.5em; 18 | } 19 | -------------------------------------------------------------------------------- /projects/lithium/checkbox/checkbox-group.element.spec.ts: -------------------------------------------------------------------------------- 1 | import 'lithium-ui/card'; 2 | import { LithiumCheckboxGroup } from 'lithium-ui/checkbox'; 3 | import { componentIsStable, createTestElement, getComponentSlotContent, removeTestElement, waitForComponent } from 'lithium-ui/test/utils'; 4 | 5 | describe('checkbox group element', () => { 6 | let testElement: HTMLElement; 7 | let component: LithiumCheckboxGroup; 8 | 9 | beforeEach(async () => { 10 | testElement = createTestElement(); 11 | testElement.innerHTML = ` 12 | 13 | hello world 14 | 15 | `; 16 | await waitForComponent('li-checkbox-group'); 17 | component = testElement.querySelector('li-checkbox-group'); 18 | }); 19 | 20 | afterEach(() => { 21 | removeTestElement(testElement); 22 | }); 23 | 24 | it('should render with appropriate slots', async () => { 25 | await componentIsStable(component); 26 | const slots = getComponentSlotContent(component); 27 | expect(slots.default).toBe('hello world'); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /projects/lithium/checkbox/checkbox-group.element.ts: -------------------------------------------------------------------------------- 1 | import { html, LitElement } from 'lit-element'; 2 | import { baseStyles, property, registerElementSafely } from 'lithium-ui/common'; 3 | import { styles } from './checkbox-group.element.css'; 4 | 5 | /** 6 | * Radio Group, group element to associate a collection of radio inputs 7 | * 8 | * @noInheritDoc 9 | * @element li-checkbox-group 10 | * @slot default - Content slot for checkbox inputs 11 | */ 12 | // @dynamic 13 | export class LithiumCheckboxGroup extends LitElement { 14 | /** Display checkbox elements inline */ 15 | @property({ type: Boolean }) inline: boolean; 16 | 17 | static get styles() { 18 | return [baseStyles, styles]; 19 | } 20 | 21 | render() { 22 | return html` 23 |
24 | 25 |
26 | `; 27 | } 28 | } 29 | 30 | registerElementSafely('li-checkbox-group', LithiumCheckboxGroup); 31 | 32 | declare global { 33 | interface HTMLElementTagNameMap { 34 | 'li-checkbox-group': LithiumCheckboxGroup; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /projects/lithium/checkbox/checkbox.element.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | --color: inherit; 3 | --color-disabled: var(--li-common-color-gray-300); 4 | --border-color: var(--li-common-color-gray-300); 5 | --background: var(--li-common-color-white-100); 6 | display: block; 7 | position: relative; 8 | margin-bottom: var(--li-common-spacing-margin-bottom-small); 9 | } 10 | 11 | ::slotted(label) { 12 | color: var(--color) !important; 13 | cursor: pointer !important; 14 | padding-left: 1.625em !important; 15 | margin-right: 1em !important; 16 | line-height: 1.5 !important; 17 | } 18 | 19 | ::slotted([type='checkbox']) { 20 | position: absolute; 21 | left: -9999px; 22 | } 23 | 24 | :host([disabled]) ::slotted(label) { 25 | color: var(--color-disabled); 26 | cursor: not-allowed !important; 27 | } 28 | 29 | .box { 30 | content: ''; 31 | position: absolute; 32 | pointer-events: none; 33 | left: 0; 34 | top: 0.2em; 35 | width: 2em; 36 | height: 2em; 37 | border: 1px solid var(--border-color); 38 | background: var(--background); 39 | border-radius: 0.3em; 40 | } 41 | 42 | li-icon { 43 | display: none; 44 | pointer-events: none; 45 | } 46 | 47 | :host([checked]) > li-icon { 48 | display: block; 49 | position: absolute; 50 | width: 1.5em; 51 | height: 1.5em; 52 | top: 0.3em; 53 | left: 0.3em; 54 | --color: inherit; 55 | } 56 | 57 | :host([focused]) ::slotted(label) { 58 | outline: var(--li-common-outline); 59 | box-shadow: var(--li-common-outline-shadow); 60 | } 61 | -------------------------------------------------------------------------------- /projects/lithium/checkbox/entrypoint.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "composite": true 5 | }, 6 | "references": [ 7 | { "path": "../common/entrypoint.tsconfig.json" }, 8 | { "path": "../input/entrypoint.tsconfig.json" }, 9 | { "path": "../icon/entrypoint.tsconfig.json" }, 10 | { "path": "../icon-shapes/entrypoint.tsconfig.json" } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /projects/lithium/checkbox/index.ts: -------------------------------------------------------------------------------- 1 | export * from './checkbox.element'; 2 | export * from './checkbox-group.element'; 3 | -------------------------------------------------------------------------------- /projects/lithium/checkbox/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "sideEffects": true, 3 | "main": "./index.js", 4 | "module": "./index.js", 5 | "typings": "./index.d.ts", 6 | "name": "lithium-ui/checkbox", 7 | "type": "module" 8 | } 9 | -------------------------------------------------------------------------------- /projects/lithium/code-example/code-example.element.spec.ts: -------------------------------------------------------------------------------- 1 | import 'lithium-ui/code-example'; 2 | import { LithiumCodeExample } from 'lithium-ui/code-example'; 3 | import { componentIsStable, createTestElement, removeTestElement, waitForComponent } from 'lithium-ui/test/utils'; 4 | 5 | describe('code example element', () => { 6 | let testElement: HTMLElement; 7 | let component: LithiumCodeExample; 8 | 9 | beforeEach(async () => { 10 | testElement = createTestElement(); 11 | testElement.innerHTML = ` 12 | 13 | `; 14 | await waitForComponent('li-code-example'); 15 | component = testElement.querySelector('li-code-example'); 16 | }); 17 | 18 | afterEach(() => { 19 | removeTestElement(testElement); 20 | }); 21 | 22 | it('should add appropriate classes for language', async () => { 23 | await componentIsStable(component); 24 | expect(component.shadowRoot.innerHTML.includes('language-javascript')).toBe(true); 25 | expect(component).toBeTruthy(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /projects/lithium/code-example/code-example.element.ts: -------------------------------------------------------------------------------- 1 | import { html, LitElement } from 'lit-element'; 2 | import { highlight, languages } from 'prismjs'; 3 | 4 | import { baseStyles, property, registerElementSafely } from 'lithium-ui/common'; 5 | import { styles } from './code-example.element.css'; 6 | 7 | /** 8 | * Code example generator with prismjs highlighting 9 | * 10 | * @noInheritDoc 11 | * @element li-code-example 12 | * @experimental 13 | */ 14 | // @dynamic 15 | export class LithiumCodeExample extends LitElement { 16 | @property({ type: String }) language = 'javascript'; 17 | @property({ type: String }) code = ''; 18 | @property({ type: String }) private renderedCode = ''; 19 | 20 | static get styles() { 21 | return [baseStyles, styles]; 22 | } 23 | 24 | render() { 25 | return html` 26 |
27 |
28 |           
29 |         
30 |
31 | `; 32 | } 33 | 34 | updated() { 35 | this.renderedCode = highlight(this.code, languages[this.language], this.language); 36 | } 37 | } 38 | 39 | registerElementSafely('li-code-example', LithiumCodeExample); 40 | 41 | declare global { 42 | interface HTMLElementTagNameMap { 43 | 'li-code-example': LithiumCodeExample; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /projects/lithium/code-example/entrypoint.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "composite": true 5 | }, 6 | "references": [{ "path": "../common/entrypoint.tsconfig.json" }] 7 | } 8 | -------------------------------------------------------------------------------- /projects/lithium/code-example/index.ts: -------------------------------------------------------------------------------- 1 | export * from './code-example.element'; 2 | -------------------------------------------------------------------------------- /projects/lithium/code-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "sideEffects": true, 3 | "main": "./index.js", 4 | "module": "./index.js", 5 | "typings": "./index.d.ts", 6 | "name": "lithium-ui/code-example", 7 | "type": "module" 8 | } 9 | -------------------------------------------------------------------------------- /projects/lithium/common/base/base.element.scss: -------------------------------------------------------------------------------- 1 | @import './../../styles/base.element'; 2 | -------------------------------------------------------------------------------- /projects/lithium/common/decorators/event.spec.ts: -------------------------------------------------------------------------------- 1 | import { LitElement } from 'lit-element'; 2 | import { event, EventEmitter, registerElementSafely } from 'lithium-ui/common'; 3 | import { componentIsStable, createTestElement, removeTestElement, waitForComponent } from 'lithium-ui/test/utils'; 4 | 5 | export class TestElement extends LitElement { 6 | @event() test: EventEmitter; 7 | } 8 | 9 | registerElementSafely('test-event-decorator', TestElement); 10 | 11 | describe('event decorator', () => { 12 | let testElement: HTMLElement; 13 | let component: TestElement; 14 | 15 | beforeEach(async () => { 16 | testElement = createTestElement(); 17 | testElement.innerHTML = ``; 18 | 19 | await waitForComponent('test-event-decorator'); 20 | component = testElement.querySelector('test-event-decorator'); 21 | }); 22 | 23 | afterEach(() => { 24 | removeTestElement(testElement); 25 | }); 26 | 27 | it('should create a event listener with a generic type', async () => { 28 | await componentIsStable(component); 29 | let value: any; 30 | component.addEventListener('test', (e: any) => (value = e.detail)); 31 | component.test.emit('hello'); 32 | 33 | await componentIsStable(component); 34 | expect(value).toBe('hello'); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /projects/lithium/common/decorators/event.ts: -------------------------------------------------------------------------------- 1 | export interface EventOptions { 2 | /** indicate if event bubbles up through the DOM or not */ 3 | bubbles?: boolean; 4 | /** indicate if event is cancelable */ 5 | cancelable?: boolean; 6 | /** indicate if event can bubble across the boundary between the shadow DOM and the light DOM */ 7 | composed?: boolean; 8 | } 9 | 10 | export class EventEmitter { 11 | constructor(private target: HTMLElement, private eventName: string) {} 12 | 13 | emit(value: T, options?: EventOptions) { 14 | this.target.dispatchEvent(new CustomEvent(this.eventName, { detail: value, ...options })); 15 | } 16 | } 17 | 18 | export function event() { 19 | return (protoOrDescriptor: any, name: string): any => { 20 | const descriptor = { 21 | get(this: HTMLElement) { 22 | return new EventEmitter(this, name !== undefined ? name : protoOrDescriptor.key); 23 | }, 24 | enumerable: true, 25 | configurable: true 26 | }; 27 | 28 | return name !== undefined ? legacyEvent(descriptor, protoOrDescriptor, name) : standardEvent(descriptor, protoOrDescriptor); 29 | }; 30 | } 31 | 32 | // Legacy TS Decorator 33 | function legacyEvent(descriptor: PropertyDescriptor, protoOrDescriptor: {}, name: PropertyKey) { 34 | Object.defineProperty(protoOrDescriptor, name, descriptor); 35 | } 36 | 37 | // TC39 Decorators proposal 38 | function standardEvent(descriptor: PropertyDescriptor, element: { key: string }) { 39 | return { 40 | kind: 'method', 41 | placement: 'prototype', 42 | key: element.key, 43 | descriptor 44 | }; 45 | } 46 | -------------------------------------------------------------------------------- /projects/lithium/common/entrypoint.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "composite": true 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /projects/lithium/common/index.ts: -------------------------------------------------------------------------------- 1 | export * from './decorators/query-slot'; 2 | export * from './decorators/property'; 3 | export * from './decorators/event'; 4 | export * from './base/button.base'; 5 | export * from './utils/register'; 6 | export * from './utils/events'; 7 | export * from './utils/enums'; 8 | export * from './services/i18n.service'; 9 | export { styles as baseStyles } from './base/base.element.css'; 10 | -------------------------------------------------------------------------------- /projects/lithium/common/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "sideEffects": false, 3 | "main": "./index.js", 4 | "module": "./index.js", 5 | "typings": "./index.d.ts", 6 | "name": "lithium-ui/common", 7 | "type": "module" 8 | } 9 | -------------------------------------------------------------------------------- /projects/lithium/common/services/i18n.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { englishRegistry, IntlService } from './i18n.service'; 2 | 3 | describe('i18n service', () => { 4 | it('should return a language registry', () => { 5 | expect(IntlService.registry.open).toBe('Open'); 6 | expect( 7 | IntlService.setRegistry({ 8 | open: 'Ouvrir', 9 | close: 'Fermer', 10 | menu: 'Menu', 11 | error: 'Erreur', 12 | warning: 'Avertissement', 13 | success: 'Succès', 14 | info: 'Information', 15 | loading: 'Chargement', 16 | nextMonth: '', 17 | previousMonth: '' 18 | }) 19 | ); 20 | 21 | expect(IntlService.registry.open).toBe('Ouvrir'); 22 | IntlService.setRegistry(englishRegistry); 23 | expect(IntlService.registry.open).toBe('Open'); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /projects/lithium/common/services/i18n.service.ts: -------------------------------------------------------------------------------- 1 | export interface InternationalizationRegistry { 2 | open: string; 3 | close: string; 4 | menu: string; 5 | error: string; 6 | warning: string; 7 | success: string; 8 | info: string; 9 | loading: string; 10 | previousMonth: string; 11 | nextMonth: string; 12 | } 13 | 14 | export const englishRegistry: InternationalizationRegistry = { 15 | open: 'Open', 16 | close: 'Close', 17 | menu: 'Menu', 18 | error: 'Error', 19 | warning: 'Warning', 20 | success: 'Success', 21 | info: 'Information', 22 | loading: 'loading', 23 | previousMonth: 'previous month', 24 | nextMonth: 'next month' 25 | }; 26 | 27 | let registryState: InternationalizationRegistry = { ...englishRegistry }; 28 | 29 | // @dynamic 30 | export class IntlService { 31 | static get registry(): InternationalizationRegistry { 32 | return { ...registryState }; 33 | } 34 | 35 | static setRegistry(registry: InternationalizationRegistry) { 36 | registryState = registry; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /projects/lithium/common/utils/enums.ts: -------------------------------------------------------------------------------- 1 | export enum KeyCodes { 2 | LeftArrow = 'ArrowUp', 3 | ArrowUp = 'ArrowUp', 4 | ArrowRight = 'ArrowRight', 5 | ArrowDown = 'ArrowDown', 6 | Backspace = 'Backspace', 7 | Tab = 'TAB', 8 | Enter = 'Enter', 9 | Escape = 'Escape', 10 | Space = 'Space' 11 | } 12 | 13 | export enum AriaRole { 14 | Presentation = 'presentation', 15 | Button = 'button' 16 | } 17 | -------------------------------------------------------------------------------- /projects/lithium/common/utils/events.ts: -------------------------------------------------------------------------------- 1 | export function stopEvent(event: Event) { 2 | event.preventDefault(); 3 | event.stopPropagation(); 4 | } 5 | -------------------------------------------------------------------------------- /projects/lithium/common/utils/register.ts: -------------------------------------------------------------------------------- 1 | export function registerElementSafely(tagName: string, elementClass: any) { 2 | const elementExists = !!customElements.get(tagName); 3 | 4 | if (elementExists) { 5 | console.warn(`${tagName} has already been registered`); 6 | } else { 7 | customElements.define(tagName, elementClass); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /projects/lithium/datalist/datalist.element.spec.ts: -------------------------------------------------------------------------------- 1 | import 'lithium-ui/datalist'; 2 | import { LithiumDatalist } from 'lithium-ui/datalist'; 3 | import { componentIsStable, createTestElement, getComponentSlotContent, removeTestElement, waitForComponent } from 'lithium-ui/test/utils'; 4 | 5 | describe('textarea element', () => { 6 | let testElement: HTMLElement; 7 | let component: LithiumDatalist; 8 | 9 | beforeEach(async () => { 10 | testElement = createTestElement(); 11 | testElement.innerHTML = ` 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | `; 22 | await waitForComponent('li-datalist'); 23 | component = testElement.querySelector('li-datalist'); 24 | }); 25 | 26 | afterEach(() => { 27 | removeTestElement(testElement); 28 | }); 29 | 30 | it('should render a datalist input with appropriate slots', async () => { 31 | await componentIsStable(component); 32 | const slots = getComponentSlotContent(component); 33 | expect(slots.default.includes('datalist label')).toBe(true); 34 | }); 35 | 36 | it('should associate the input with the datalist', async () => { 37 | await componentIsStable(component); 38 | const input = testElement.querySelector('input'); 39 | const datalist = testElement.querySelector('datalist'); 40 | expect(input.getAttribute('list')).toBe(datalist.getAttribute('id')); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /projects/lithium/datalist/datalist.element.ts: -------------------------------------------------------------------------------- 1 | import { property, querySlot, registerElementSafely } from 'lithium-ui/common'; 2 | import { LithiumInput } from 'lithium-ui/input'; 3 | 4 | /** 5 | * Input, standard textarea with accessibility and error enhancements. 6 | * 7 | * @noInheritDoc 8 | * @element li-datalist 9 | * @slot default - Content slot for modal body 10 | * @cssprop --color 11 | * @cssprop --color-error 12 | * @cssprop --background 13 | * @cssprop --background-disabled 14 | * @cssprop --border-color 15 | * @cssprop --border-radius 16 | */ 17 | // @dynamic 18 | export class LithiumDatalist extends LithiumInput { 19 | /** Set input in an error state */ 20 | @property({ type: Boolean }) error: boolean; 21 | 22 | private listId = `${this.inputId}-list`; 23 | 24 | @querySlot('datalist') private datalist: HTMLDataListElement; 25 | 26 | connectedCallback() { 27 | super.connectedCallback(); 28 | this.datalist.id = this.listId; 29 | this.input.setAttribute('list', this.listId); 30 | } 31 | } 32 | 33 | registerElementSafely('li-datalist', LithiumDatalist); 34 | 35 | declare global { 36 | interface HTMLElementTagNameMap { 37 | 'li-datalist': LithiumDatalist; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /projects/lithium/datalist/entrypoint.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "composite": true 5 | }, 6 | "references": [{ "path": "../common/entrypoint.tsconfig.json" }, { "path": "../input/entrypoint.tsconfig.json" }] 7 | } 8 | -------------------------------------------------------------------------------- /projects/lithium/datalist/index.ts: -------------------------------------------------------------------------------- 1 | export * from './datalist.element'; 2 | -------------------------------------------------------------------------------- /projects/lithium/datalist/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "sideEffects": true, 3 | "main": "./index.js", 4 | "module": "./index.js", 5 | "typings": "./index.d.ts", 6 | "name": "lithium-ui/datalist", 7 | "type": "module" 8 | } 9 | -------------------------------------------------------------------------------- /projects/lithium/datepicker/entrypoint.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "composite": true 5 | }, 6 | "references": [{ "path": "../common/entrypoint.tsconfig.json" }, { "path": "../input/entrypoint.tsconfig.json" }] 7 | } 8 | -------------------------------------------------------------------------------- /projects/lithium/datepicker/index.ts: -------------------------------------------------------------------------------- 1 | export * from './datepicker.element'; 2 | export * from './datepicker-inline.element'; 3 | -------------------------------------------------------------------------------- /projects/lithium/datepicker/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "sideEffects": true, 3 | "main": "./index.js", 4 | "module": "./index.js", 5 | "typings": "./index.d.ts", 6 | "name": "lithium-ui/datepicker", 7 | "type": "module" 8 | } 9 | -------------------------------------------------------------------------------- /projects/lithium/dropdown/dropdown.element.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | font-family: inherit; 3 | font-size: 10px !important; 4 | } 5 | 6 | .dropdown div { 7 | border: 1px solid #ccc; 8 | padding: 1.2em; 9 | color: inherit; 10 | } 11 | 12 | .dropdown .btn { 13 | padding: 1.2em; 14 | font-family: inherit; 15 | color: inherit; 16 | font-size: 1.6em; 17 | } 18 | 19 | .x-dropdown-slot::slotted(p) { 20 | font-size: 1.6em !important; 21 | color: red; 22 | } 23 | -------------------------------------------------------------------------------- /projects/lithium/dropdown/dropdown.element.ts: -------------------------------------------------------------------------------- 1 | import { html, LitElement } from 'lit-element'; 2 | 3 | import { baseStyles, event, EventEmitter, property, registerElementSafely } from 'lithium-ui/common'; 4 | import { styles } from './dropdown.element.css'; 5 | 6 | // test component, not for production 7 | // @dynamic 8 | export class XDropdown extends LitElement { 9 | @event() private openChange: EventEmitter; 10 | 11 | private _open = false; 12 | get open() { 13 | return this._open; 14 | } 15 | 16 | @property({ type: Boolean }) 17 | set open(value) { 18 | if (value !== this._open) { 19 | const old = this._open; 20 | this._open = value; 21 | this.requestUpdate('open', old); 22 | this.openChange.emit(this._open); 23 | } 24 | } 25 | 26 | @property({ type: String }) 27 | title = 'dropdown'; 28 | 29 | static get styles() { 30 | return [baseStyles, styles]; 31 | } 32 | 33 | render() { 34 | return html` 35 | 45 | `; 46 | } 47 | 48 | toggle() { 49 | this.open = !this.open; 50 | } 51 | } 52 | 53 | registerElementSafely('x-dropdown', XDropdown); 54 | 55 | declare global { 56 | interface HTMLElementTagNameMap { 57 | 'li-dropdown': XDropdown; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /projects/lithium/dropdown/entrypoint.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "composite": true 5 | }, 6 | "references": [{ "path": "../common/entrypoint.tsconfig.json" }] 7 | } 8 | -------------------------------------------------------------------------------- /projects/lithium/dropdown/index.ts: -------------------------------------------------------------------------------- 1 | export * from './dropdown.element'; 2 | -------------------------------------------------------------------------------- /projects/lithium/dropdown/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "sideEffects": true, 3 | "main": "./index.js", 4 | "module": "./index.js", 5 | "typings": "./index.d.ts", 6 | "name": "lithium-ui/dropdown", 7 | "type": "module" 8 | } 9 | -------------------------------------------------------------------------------- /projects/lithium/form/entrypoint.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "composite": true 5 | }, 6 | "references": [{ "path": "../common/entrypoint.tsconfig.json" }] 7 | } 8 | -------------------------------------------------------------------------------- /projects/lithium/form/form.element.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | display: block; 3 | overflow: auto; 4 | } 5 | -------------------------------------------------------------------------------- /projects/lithium/form/form.element.spec.ts: -------------------------------------------------------------------------------- 1 | import 'lithium-ui/form'; 2 | import { LithiumForm } from 'lithium-ui/form'; 3 | import { componentIsStable, createTestElement, getComponentSlotContent, removeTestElement, waitForComponent } from 'lithium-ui/test/utils'; 4 | 5 | describe('form element', () => { 6 | let testElement: HTMLElement; 7 | let component: LithiumForm; 8 | 9 | beforeEach(async () => { 10 | testElement = createTestElement(); 11 | testElement.innerHTML = ` 12 | 13 | hello world 14 | 15 | `; 16 | await waitForComponent('li-form'); 17 | component = testElement.querySelector('li-form'); 18 | }); 19 | 20 | afterEach(() => { 21 | removeTestElement(testElement); 22 | }); 23 | 24 | it('should render a form with appropriate slots', async () => { 25 | await componentIsStable(component); 26 | const slots = getComponentSlotContent(component); 27 | expect(slots.default).toBe('hello world'); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /projects/lithium/form/form.element.ts: -------------------------------------------------------------------------------- 1 | import { html, LitElement } from 'lit-element'; 2 | 3 | import { baseStyles, registerElementSafely } from 'lithium-ui/common'; 4 | import { styles } from './form.element.css'; 5 | 6 | /** 7 | * Form, wrapper container for basic form styles 8 | * 9 | * @noInheritDoc 10 | * @element li-form 11 | * @slot default - Content slot for checkbox inputs 12 | */ 13 | // @dynamic 14 | export class LithiumForm extends LitElement { 15 | static get styles() { 16 | return [baseStyles, styles]; 17 | } 18 | 19 | render() { 20 | return html` 21 | 22 | `; 23 | } 24 | } 25 | 26 | registerElementSafely('li-form', LithiumForm); 27 | 28 | declare global { 29 | interface HTMLElementTagNameMap { 30 | 'li-form': LithiumForm; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /projects/lithium/form/index.ts: -------------------------------------------------------------------------------- 1 | export * from './form.element'; 2 | -------------------------------------------------------------------------------- /projects/lithium/form/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "sideEffects": true, 3 | "main": "./index.js", 4 | "module": "./index.js", 5 | "typings": "./index.d.ts", 6 | "name": "lithium-ui/form", 7 | "type": "module" 8 | } 9 | -------------------------------------------------------------------------------- /projects/lithium/icon-shapes/entrypoint.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "composite": true 5 | }, 6 | "references": [{ "path": "../common/entrypoint.tsconfig.json" }] 7 | } 8 | -------------------------------------------------------------------------------- /projects/lithium/icon-shapes/icon.element.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | --color: var(--li-common-color-gray-500); 3 | --width: 2.4em; 4 | --height: 2.4em; 5 | width: var(--width); 6 | height: var(--height); 7 | display: inline-block; 8 | overflow: hidden; 9 | } 10 | 11 | svg { 12 | fill: var(--color); 13 | } 14 | -------------------------------------------------------------------------------- /projects/lithium/icon-shapes/icon.element.spec.ts: -------------------------------------------------------------------------------- 1 | import 'lithium-ui/icon'; 2 | import { IconService, LithiumIcon, menuIcon } from 'lithium-ui/icon-shapes'; 3 | IconService.addIcons(menuIcon); 4 | import { componentIsStable, createTestElement, removeTestElement, waitForComponent } from 'lithium-ui/test/utils'; 5 | 6 | describe('icon element', () => { 7 | let testElement: HTMLElement; 8 | let component: LithiumIcon; 9 | 10 | beforeEach(async () => { 11 | testElement = createTestElement(); 12 | testElement.innerHTML = `test`; 13 | await waitForComponent('li-icon'); 14 | component = testElement.querySelector('li-icon'); 15 | }); 16 | 17 | afterEach(() => { 18 | removeTestElement(testElement); 19 | }); 20 | 21 | it('should render a icon with default fallback', async () => { 22 | await componentIsStable(component); 23 | expect(component.shadowRoot.innerHTML).toContain('li-icon-unknown'); 24 | 25 | component.name = 'hi'; 26 | await componentIsStable(component); 27 | expect(component.shadowRoot.innerHTML).toContain('li-icon-unknown'); 28 | }); 29 | 30 | it('should render a icon with set name', async () => { 31 | component.name = 'menu'; 32 | await componentIsStable(component); 33 | expect(component.shadowRoot.innerHTML).toContain('li-icon-menu'); 34 | }); 35 | 36 | it('should associate the svg image to a label using aria-labelledbyif title is set', async () => { 37 | component.title = 'test'; 38 | await componentIsStable(component); 39 | const svg = component.shadowRoot.querySelector('svg'); 40 | const labelId = component.shadowRoot.querySelector('.li-sr-only').getAttribute('id'); 41 | expect(svg.getAttribute('aria-labelledby')).toBe(labelId); 42 | expect(svg.getAttribute('role')).toBe('img'); 43 | }); 44 | }); 45 | -------------------------------------------------------------------------------- /projects/lithium/icon-shapes/icon.service.spec.ts: -------------------------------------------------------------------------------- 1 | import 'lithium-ui/icon'; 2 | import { allIconsCollection, IconService } from 'lithium-ui/icon-shapes'; 3 | IconService.addIconCollection(allIconsCollection); 4 | 5 | describe('IconService', () => { 6 | it('should return a icon registry', () => { 7 | expect(IconService.registry.menu).toContain('li-icon-menu'); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /projects/lithium/icon-shapes/icon.service.ts: -------------------------------------------------------------------------------- 1 | import { SVGIcon, SVGIconCollection, unknownIcon } from './svg'; 2 | 3 | const iconRegistry = { 4 | [unknownIcon.name]: unknownIcon.svg 5 | }; 6 | 7 | // @dynamic 8 | export class IconService { 9 | static get registry() { 10 | return { ...iconRegistry }; 11 | } 12 | 13 | static addIcons(...svgIcons: SVGIcon[]) { 14 | svgIcons.forEach(icon => (iconRegistry[icon.name] = icon.svg)); 15 | } 16 | 17 | static addIconCollection(...svgIconCollection: SVGIconCollection[]) { 18 | svgIconCollection.forEach(group => { 19 | group.icons.forEach(icon => (iconRegistry[icon.name] = icon.svg)); 20 | }); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /projects/lithium/icon-shapes/index.ts: -------------------------------------------------------------------------------- 1 | export * from './icon.element'; 2 | export * from './icon.service'; 3 | export * from './svg'; 4 | -------------------------------------------------------------------------------- /projects/lithium/icon-shapes/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "sideEffects": false, 3 | "main": "./index.js", 4 | "module": "./index.js", 5 | "typings": "./index.d.ts", 6 | "name": "lithium-ui/icon-shapes", 7 | "type": "module" 8 | } 9 | -------------------------------------------------------------------------------- /projects/lithium/icon/entrypoint.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "composite": true 5 | }, 6 | "references": [{ "path": "../common/entrypoint.tsconfig.json" }, { "path": "../icon-shapes/entrypoint.tsconfig.json" }] 7 | } 8 | -------------------------------------------------------------------------------- /projects/lithium/icon/index.ts: -------------------------------------------------------------------------------- 1 | import { registerElementSafely } from 'lithium-ui/common'; 2 | import { LithiumIcon } from 'lithium-ui/icon-shapes'; 3 | 4 | registerElementSafely('li-icon', LithiumIcon); 5 | 6 | declare global { 7 | interface HTMLElementTagNameMap { 8 | 'li-icon': LithiumIcon; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /projects/lithium/icon/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "sideEffects": true, 3 | "main": "./index.js", 4 | "module": "./index.js", 5 | "typings": "./index.d.ts", 6 | "name": "lithium-ui/icon", 7 | "type": "module" 8 | } 9 | -------------------------------------------------------------------------------- /projects/lithium/index.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Public API Surface of lithium 3 | */ 4 | 5 | export { IntlService, InternationalizationRegistry, englishRegistry } from 'lithium-ui/common'; 6 | -------------------------------------------------------------------------------- /projects/lithium/input/entrypoint.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "composite": true 5 | }, 6 | "references": [{ "path": "../common/entrypoint.tsconfig.json" }] 7 | } 8 | -------------------------------------------------------------------------------- /projects/lithium/input/index.ts: -------------------------------------------------------------------------------- 1 | export * from './input.element'; 2 | export * from './input-error.element'; 3 | export * from './input-message.element'; 4 | -------------------------------------------------------------------------------- /projects/lithium/input/input-error.element.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | --color: var(--li-common-color-red-50); 3 | display: block; 4 | color: var(--color); 5 | } 6 | -------------------------------------------------------------------------------- /projects/lithium/input/input-error.element.ts: -------------------------------------------------------------------------------- 1 | import { html, LitElement } from 'lit-element'; 2 | import { baseStyles, registerElementSafely } from 'lithium-ui/common'; 3 | import { styles } from './input-error.element.css'; 4 | 5 | /** 6 | * Input error, display error validation messages related for inputs 7 | * 8 | * @noInheritDoc 9 | * @element li-input-error 10 | * @slot default - Text content for message 11 | * @cssprop --color 12 | */ 13 | // @dynamic 14 | export class LithiumInputError extends LitElement { 15 | static get styles() { 16 | return [baseStyles, styles]; 17 | } 18 | 19 | render() { 20 | return html` 21 | 22 | `; 23 | } 24 | 25 | connectedCallback() { 26 | super.connectedCallback(); 27 | this.setAttribute('aria-live', 'polite'); 28 | } 29 | } 30 | 31 | registerElementSafely('li-input-error', LithiumInputError); 32 | 33 | declare global { 34 | interface HTMLElementTagNameMap { 35 | 'li-input-error': LithiumInputError; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /projects/lithium/input/input-error.spec.ts: -------------------------------------------------------------------------------- 1 | import 'lithium-ui/input'; 2 | import { LithiumInputError } from 'lithium-ui/input'; 3 | import { componentIsStable, createTestElement, getComponentSlotContent, removeTestElement, waitForComponent } from 'lithium-ui/test/utils'; 4 | 5 | describe('input error element', () => { 6 | let testElement: HTMLElement; 7 | let component: LithiumInputError; 8 | 9 | beforeEach(async () => { 10 | testElement = createTestElement(); 11 | testElement.innerHTML = ` 12 | 13 | test error 14 | 15 | `; 16 | await waitForComponent('li-input-error'); 17 | component = testElement.querySelector('li-input-error'); 18 | }); 19 | 20 | afterEach(() => { 21 | removeTestElement(testElement); 22 | }); 23 | 24 | it('should render the message with appropriate slots', async () => { 25 | await componentIsStable(component); 26 | const slots = getComponentSlotContent(component); 27 | expect(slots.default.includes('test error')).toBe(true); 28 | }); 29 | 30 | it('should apply the appropriate aria live attribute', async () => { 31 | await componentIsStable(component); 32 | expect(component.getAttribute('aria-live')).toBe('polite'); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /projects/lithium/input/input-message.element.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | display: block; 3 | } 4 | 5 | slot { 6 | font-size: 1.4em !important; 7 | } 8 | -------------------------------------------------------------------------------- /projects/lithium/input/input-message.element.ts: -------------------------------------------------------------------------------- 1 | import { html, LitElement } from 'lit-element'; 2 | import { baseStyles, registerElementSafely } from 'lithium-ui/common'; 3 | import { styles } from './input-message.element.css'; 4 | 5 | /** 6 | * Input message, display messages related for inputs 7 | * 8 | * @noInheritDoc 9 | * @element li-input-message 10 | * @slot default - Text content for message 11 | */ 12 | // @dynamic 13 | export class LithiumInputMessage extends LitElement { 14 | static get styles() { 15 | return [baseStyles, styles]; 16 | } 17 | 18 | render() { 19 | return html` 20 | 21 | `; 22 | } 23 | } 24 | 25 | registerElementSafely('li-input-message', LithiumInputMessage); 26 | 27 | declare global { 28 | interface HTMLElementTagNameMap { 29 | 'li-input-message': LithiumInputMessage; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /projects/lithium/input/input-message.spec.ts: -------------------------------------------------------------------------------- 1 | import 'lithium-ui/input'; 2 | import { LithiumInputMessage } from 'lithium-ui/input'; 3 | import { componentIsStable, createTestElement, getComponentSlotContent, removeTestElement, waitForComponent } from 'lithium-ui/test/utils'; 4 | 5 | describe('input message element', () => { 6 | let testElement: HTMLElement; 7 | let component: LithiumInputMessage; 8 | 9 | beforeEach(async () => { 10 | testElement = createTestElement(); 11 | testElement.innerHTML = ` 12 | 13 | test message 14 | 15 | `; 16 | await waitForComponent('li-input-message'); 17 | component = testElement.querySelector('li-input-message'); 18 | }); 19 | 20 | afterEach(() => { 21 | removeTestElement(testElement); 22 | }); 23 | 24 | it('should render the message with appropriate slots', async () => { 25 | await componentIsStable(component); 26 | const slots = getComponentSlotContent(component); 27 | expect(slots.default.includes('test message')).toBe(true); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /projects/lithium/input/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "sideEffects": true, 3 | "main": "./index.js", 4 | "module": "./index.js", 5 | "typings": "./index.d.ts", 6 | "name": "lithium-ui/input", 7 | "type": "module" 8 | } 9 | -------------------------------------------------------------------------------- /projects/lithium/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, '../../coverage/lithium'), 20 | reports: ['html', 'lcovonly', 'text-summary'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false, 30 | restartOnFileChange: true, 31 | customLaunchers: { 32 | ChromeHeadlessCustom: { 33 | base: 'ChromeHeadless', 34 | flags: ['--no-sandbox', '--disable-gpu'] 35 | } 36 | }, 37 | }); 38 | }; 39 | -------------------------------------------------------------------------------- /projects/lithium/message/entrypoint.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "composite": true 5 | }, 6 | "references": [ 7 | { "path": "../common/entrypoint.tsconfig.json" }, 8 | { "path": "../icon/entrypoint.tsconfig.json" }, 9 | { "path": "../icon-shapes/entrypoint.tsconfig.json" } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /projects/lithium/message/index.ts: -------------------------------------------------------------------------------- 1 | export * from './message.element'; 2 | -------------------------------------------------------------------------------- /projects/lithium/message/message.element.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | --color: var(--li-common-color-white-100); 3 | --background: var(--li-common-color-blue-100); 4 | --border-radius: var(--li-common-border-radius); 5 | --border: 0; 6 | --padding: 1.6em 5.6em; 7 | --status-icon-color: var(--color); 8 | --close-icon-color: var(--color); 9 | color: var(--color); 10 | background: var(--background); 11 | border: var(--border); 12 | border-radius: var(--border-radius); 13 | display: block; 14 | padding: var(--padding); 15 | margin-bottom: var(--li-common-spacing-margin-bottom); 16 | position: relative; 17 | } 18 | 19 | :host([close]) { 20 | display: none; 21 | } 22 | 23 | :host([status='success']) { 24 | --background: var(--li-common-color-green-100); 25 | } 26 | 27 | :host([status='warning']) { 28 | --background: var(--li-common-color-orange-100); 29 | } 30 | 31 | :host([status='error']) { 32 | --background: var(--li-common-color-red-100); 33 | } 34 | 35 | ::slotted(p) { 36 | margin-bottom: 0 !important; 37 | } 38 | 39 | .li-type-icon li-icon { 40 | --width: 2em; 41 | --height: 2em; 42 | --color: var(--status-icon-color); 43 | line-height: 2.4em; 44 | position: absolute; 45 | top: 1.65em; 46 | left: 1.6em; 47 | } 48 | 49 | .li-close-btn { 50 | background: transparent; 51 | border: 0; 52 | cursor: pointer; 53 | position: absolute; 54 | width: 3.8em; 55 | height: 3.8em; 56 | top: 0.65em; 57 | right: 0.65em; 58 | background: rgba(0, 0, 0, 0.2); 59 | line-height: 0; 60 | border-radius: 0.2em; 61 | } 62 | 63 | .li-close-btn li-icon { 64 | --color: var(--close-icon-color); 65 | --width: 2.4em; 66 | --height: 2.4em; 67 | } 68 | 69 | .li-close-btn:hover, 70 | .li-close-btn:focus { 71 | background: rgba(0, 0, 0, 0.2); 72 | } 73 | -------------------------------------------------------------------------------- /projects/lithium/message/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "sideEffects": true, 3 | "main": "./index.js", 4 | "module": "./index.js", 5 | "typings": "./index.d.ts", 6 | "name": "lithium-ui/message", 7 | "type": "module" 8 | } 9 | -------------------------------------------------------------------------------- /projects/lithium/modal/entrypoint.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "composite": true 5 | }, 6 | "references": [ 7 | { "path": "../common/entrypoint.tsconfig.json" }, 8 | { "path": "../icon/entrypoint.tsconfig.json" }, 9 | { "path": "../icon-shapes/entrypoint.tsconfig.json" } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /projects/lithium/modal/index.ts: -------------------------------------------------------------------------------- 1 | export * from './modal.element'; 2 | export * from './modal-actions.element'; 3 | export * from './modal-content.element'; 4 | export * from './modal-header.element'; 5 | -------------------------------------------------------------------------------- /projects/lithium/modal/modal-actions.element.ts: -------------------------------------------------------------------------------- 1 | import { html, LitElement } from 'lit-element'; 2 | 3 | import { registerElementSafely } from 'lithium-ui/common'; 4 | 5 | export class LithiumModalActions extends LitElement { 6 | connectedCallback() { 7 | super.connectedCallback(); 8 | this.setAttribute('slot', 'actions'); 9 | } 10 | 11 | protected render() { 12 | return html` 13 | 14 | `; 15 | } 16 | } 17 | 18 | registerElementSafely('li-modal-actions', LithiumModalActions); 19 | 20 | declare global { 21 | interface HTMLElementTagNameMap { 22 | 'li-modal-actions': LithiumModalActions; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /projects/lithium/modal/modal-content.element.ts: -------------------------------------------------------------------------------- 1 | import { html, LitElement } from 'lit-element'; 2 | 3 | import { registerElementSafely } from 'lithium-ui/common'; 4 | 5 | export class LithiumModalContent extends LitElement { 6 | protected render() { 7 | return html` 8 | 9 | `; 10 | } 11 | } 12 | 13 | registerElementSafely('li-modal-content', LithiumModalContent); 14 | 15 | declare global { 16 | interface HTMLElementTagNameMap { 17 | 'li-modal-content': LithiumModalContent; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /projects/lithium/modal/modal-header.element.ts: -------------------------------------------------------------------------------- 1 | import { html, LitElement } from 'lit-element'; 2 | 3 | import { registerElementSafely } from 'lithium-ui/common'; 4 | 5 | export class LithiumModalHeader extends LitElement { 6 | connectedCallback() { 7 | super.connectedCallback(); 8 | this.setAttribute('slot', 'header'); 9 | } 10 | 11 | protected render() { 12 | return html` 13 | 14 | `; 15 | } 16 | } 17 | 18 | registerElementSafely('li-modal-header', LithiumModalHeader); 19 | 20 | declare global { 21 | interface HTMLElementTagNameMap { 22 | 'li-modal-header': LithiumModalHeader; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /projects/lithium/modal/modal.element.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | --border: 1px solid var(--li-common-color-gray-300); 3 | --background: var(--li-common-color-white-100); 4 | --color: var(--li-common-color-gray-500); 5 | --max-width: 60em; 6 | --max-height: initial; 7 | --margin: 10vh auto 0 auto; 8 | --border-radius: 0.4em; 9 | --backdrop-background: rgba(0, 0, 0, 0.5); 10 | } 11 | 12 | :host([size='lg']) .li-modal { 13 | max-width: 70em; 14 | } 15 | 16 | .li-modal-wrapper { 17 | position: absolute; 18 | top: 0; 19 | left: 0; 20 | right: 0; 21 | bottom: 0; 22 | z-index: 300; 23 | overscroll-behavior: contain; 24 | } 25 | 26 | .li-modal { 27 | border: var(--border); 28 | padding: 1.6em; 29 | background: var(--background); 30 | color: var(--color); 31 | width: 100%; 32 | max-width: var(--max-width); 33 | max-height: var(--max-height); 34 | margin: var(--margin); 35 | position: relative; 36 | border-radius: var(--border-radius); 37 | z-index: 302; 38 | } 39 | 40 | .li-modal-close-btn { 41 | position: absolute; 42 | text-align: center; 43 | width: auto; 44 | height: auto; 45 | padding: 0.4em 0.5em; 46 | font-size: 2.4em; 47 | top: 0; 48 | right: 0; 49 | line-height: 1.5; 50 | border: 0; 51 | background: transparent; 52 | cursor: pointer; 53 | } 54 | 55 | li-icon { 56 | --color: var(--color); 57 | } 58 | 59 | .li-modal-backdrop { 60 | background: var(--backdrop-background); 61 | position: fixed; 62 | top: 0; 63 | bottom: 0; 64 | right: 0; 65 | left: 0; 66 | z-index: 301; 67 | } 68 | -------------------------------------------------------------------------------- /projects/lithium/modal/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "sideEffects": true, 3 | "main": "./index.js", 4 | "module": "./index.js", 5 | "typings": "./index.d.ts", 6 | "name": "lithium-ui/modal", 7 | "type": "module" 8 | } 9 | -------------------------------------------------------------------------------- /projects/lithium/nav-bar/entrypoint.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "composite": true 5 | }, 6 | "references": [{ "path": "../common/entrypoint.tsconfig.json" }] 7 | } 8 | -------------------------------------------------------------------------------- /projects/lithium/nav-bar/index.ts: -------------------------------------------------------------------------------- 1 | export * from './nav-bar.element'; 2 | -------------------------------------------------------------------------------- /projects/lithium/nav-bar/nav-bar.element.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | --background: var(--li-common-color-white-100); 3 | --background-hover: var(--li-common-color-gray-100); 4 | --box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); 5 | --color: var(--li-common-color-gray-500); 6 | background: var(--background); 7 | box-shadow: var(--box-shadow); 8 | color: var(--color); 9 | margin-bottom: var(--li-common-spacing-margin-bottom); 10 | display: flex; 11 | width: 100%; 12 | overflow: hidden; 13 | line-height: 2.4em; 14 | } 15 | 16 | :host([sticky]) { 17 | position: fixed; 18 | z-index: 100; 19 | margin-bottom: 0; 20 | } 21 | 22 | ::slotted(a), 23 | ::slotted(button) { 24 | color: var(--color) !important; 25 | display: flex; 26 | align-items: center; 27 | height: 100%; 28 | padding: 1em; 29 | background-color: transparent; 30 | border: 0; 31 | text-decoration: none; 32 | line-height: 1.5 !important; 33 | cursor: pointer; 34 | } 35 | 36 | ::slotted(a:hover), 37 | ::slotted(button:hover) { 38 | background: var(--background-hover) !important; 39 | } 40 | 41 | ::slotted([li-nav-bar-right]) { 42 | margin-left: auto !important; 43 | } 44 | -------------------------------------------------------------------------------- /projects/lithium/nav-bar/nav-bar.element.spec.ts: -------------------------------------------------------------------------------- 1 | import 'lithium-ui/nav-bar'; 2 | import { LithiumNavBar } from 'lithium-ui/nav-bar'; 3 | import { componentIsStable, createTestElement, getComponentSlotContent, removeTestElement, waitForComponent } from 'lithium-ui/test/utils'; 4 | 5 | describe('card element', () => { 6 | let testElement: HTMLElement; 7 | let component: LithiumNavBar; 8 | 9 | beforeEach(async () => { 10 | testElement = createTestElement(); 11 | testElement.innerHTML = ` 12 | 13 | link 14 | 15 | `; 16 | await waitForComponent('li-nav-bar'); 17 | component = testElement.querySelector('li-nav-bar'); 18 | }); 19 | 20 | afterEach(() => { 21 | removeTestElement(testElement); 22 | }); 23 | 24 | it('should render a nav bar with appropriate slots', async () => { 25 | await componentIsStable(component); 26 | const slots = getComponentSlotContent(component); 27 | expect(slots.default).toBe('link'); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /projects/lithium/nav-bar/nav-bar.element.ts: -------------------------------------------------------------------------------- 1 | import { html, LitElement } from 'lit-element'; 2 | 3 | import { baseStyles, property, registerElementSafely } from 'lithium-ui/common'; 4 | import { styles } from './nav-bar.element.css'; 5 | 6 | /** 7 | * Nav Bar, standard navigation bar with basic layout 8 | * 9 | * @noInheritDoc 10 | * @element li-nav-bar 11 | * @slot default - Content slot for nav bar 12 | * @attr {String} li-nav-bar-right - Align nav links to right 13 | * @cssprop --background 14 | * @cssprop --background-hover 15 | * @cssprop --box-shadow 16 | * @cssprop --color 17 | */ 18 | // @dynamic 19 | export class LithiumNavBar extends LitElement { 20 | /** Make nav bar sticky and position to top of page */ 21 | @property({ type: Boolean }) sticky: boolean; 22 | 23 | static get styles() { 24 | return [baseStyles, styles]; 25 | } 26 | 27 | render() { 28 | return html` 29 | 30 | `; 31 | } 32 | } 33 | 34 | registerElementSafely('li-nav-bar', LithiumNavBar); 35 | 36 | declare global { 37 | interface HTMLElementTagNameMap { 38 | 'li-nav-bar': LithiumNavBar; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /projects/lithium/nav-bar/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "sideEffects": true, 3 | "main": "./index.js", 4 | "module": "./index.js", 5 | "typings": "./index.d.ts", 6 | "name": "lithium-ui/nav-bar", 7 | "type": "module" 8 | } 9 | -------------------------------------------------------------------------------- /projects/lithium/package.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs-extra'); 4 | const path = require('path'); 5 | const del = require('del'); 6 | 7 | // Temporary script needed for modern build tools that default that expect es2015 modules as the main entry point. 8 | // https://github.com/ng-packagr/ng-packagr/pull/1372 9 | // https://github.com/ng-packagr/ng-packagr/issues/1318 10 | // https://github.com/angular/angular/issues/33395 11 | // https://justinfagnani.com/2019/11/01/how-to-publish-web-components-to-npm/ 12 | const read = (dir) => fs.readdirSync(dir).reduce((files, file) => 13 | fs.statSync(path.join(dir, file)).isDirectory() ? 14 | files.concat(read(path.join(dir, file))) : 15 | files.concat(path.join(dir, file)), 16 | []); 17 | 18 | del.sync(['./dist/lithium/**/*.{tsbuildinfo,ngsummary.json}', './dist/lithium/*.{tsbuildinfo,ngsummary.json}']); 19 | 20 | read('./dist/lithium').filter(f => f.includes('package.json')).forEach(file => { 21 | const data = fs.readJsonSync(file); 22 | ['__processed_by_ivy_ngcc__', 'scripts'].forEach(p => delete data[p]); 23 | fs.writeJsonSync(file, data, { spaces: 2 }); 24 | }); -------------------------------------------------------------------------------- /projects/lithium/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lithium-ui", 3 | "version": "0.0.34", 4 | "dependencies": { 5 | "lit-element": "^2.2.1", 6 | "lit-html": "^1.1.2", 7 | "prismjs": "^1.16.0", 8 | "@a11y/focus-trap": "^1.0.2", 9 | "date-fns": "^2.2.1", 10 | "tslib": "^1.10.0", 11 | "resize-observer-polyfill": "^1.5.1" 12 | } 13 | } -------------------------------------------------------------------------------- /projects/lithium/pro/README.md: -------------------------------------------------------------------------------- 1 | # Pro Components 2 | 3 | Pro components (components contained within this directory) are free to use for 4 | non commercial purposes as defined in `LICENSE.md`. To purchase a commercial 5 | license visit [lithiumui.dev/pricing](https://lithiumui.dev/pricing). -------------------------------------------------------------------------------- /projects/lithium/progress/entrypoint.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "composite": true 5 | }, 6 | "references": [{ "path": "../common/entrypoint.tsconfig.json" }] 7 | } 8 | -------------------------------------------------------------------------------- /projects/lithium/progress/index.ts: -------------------------------------------------------------------------------- 1 | export * from './progress.element'; 2 | -------------------------------------------------------------------------------- /projects/lithium/progress/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "sideEffects": true, 3 | "main": "./index.js", 4 | "module": "./index.js", 5 | "typings": "./index.d.ts", 6 | "name": "lithium-ui/progress", 7 | "type": "module" 8 | } 9 | -------------------------------------------------------------------------------- /projects/lithium/progress/progress.element.spec.ts: -------------------------------------------------------------------------------- 1 | import 'lithium-ui/progress'; 2 | import { LithiumProgress } from 'lithium-ui/progress'; 3 | import { componentIsStable, createTestElement, removeTestElement, waitForComponent } from 'lithium-ui/test/utils'; 4 | 5 | describe('card element', () => { 6 | let testElement: HTMLElement; 7 | let component: LithiumProgress; 8 | 9 | beforeEach(async () => { 10 | testElement = createTestElement(); 11 | testElement.innerHTML = ` 12 | 13 | `; 14 | await waitForComponent('li-progress'); 15 | component = testElement.querySelector('li-progress'); 16 | }); 17 | 18 | afterEach(() => { 19 | removeTestElement(testElement); 20 | }); 21 | 22 | it('should render a progress', async () => { 23 | component.value = 50; 24 | await componentIsStable(component); 25 | expect(component.shadowRoot.innerHTML.includes('progress-bar__value')).toBe(true); 26 | expect(component.shadowRoot.innerHTML.includes('50%')).toBe(true); 27 | 28 | component.showValue = false; 29 | await componentIsStable(component); 30 | expect(component.shadowRoot.innerHTML.includes('progress-bar__value')).toBe(false); 31 | }); 32 | 33 | it('should hide value when circular intermediate settings', async () => { 34 | component.value = 50; 35 | component.circular = true; 36 | await componentIsStable(component); 37 | expect(component.shadowRoot.innerHTML.includes('50%')).toBe(true); 38 | 39 | component.intermediate = true; 40 | await componentIsStable(component); 41 | expect(component.shadowRoot.innerHTML.includes('50%')).toBe(false); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /projects/lithium/radio/entrypoint.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "composite": true 5 | }, 6 | "references": [ 7 | { "path": "../common/entrypoint.tsconfig.json" }, 8 | { "path": "../input/entrypoint.tsconfig.json" }, 9 | { "path": "../icon/entrypoint.tsconfig.json" }, 10 | { "path": "../icon-shapes/entrypoint.tsconfig.json" } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /projects/lithium/radio/index.ts: -------------------------------------------------------------------------------- 1 | export * from './radio.element'; 2 | export * from './radio-group.element'; 3 | -------------------------------------------------------------------------------- /projects/lithium/radio/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "sideEffects": true, 3 | "main": "./index.js", 4 | "module": "./index.js", 5 | "typings": "./index.d.ts", 6 | "name": "lithium-ui/radio", 7 | "type": "module" 8 | } 9 | -------------------------------------------------------------------------------- /projects/lithium/radio/radio-group.element.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | display: block; 3 | } 4 | 5 | :host([inline]) ::slotted(li-radio) { 6 | display: inline-block !important; 7 | } 8 | 9 | fieldset { 10 | border: 0; 11 | padding: 0; 12 | margin: 0; 13 | } 14 | 15 | ::slotted(legend) { 16 | display: block; 17 | margin-bottom: 0.5em; 18 | } 19 | -------------------------------------------------------------------------------- /projects/lithium/radio/radio-group.element.spec.ts: -------------------------------------------------------------------------------- 1 | import 'lithium-ui/radio'; 2 | import { LithiumRadioGroup } from 'lithium-ui/radio'; 3 | import { componentIsStable, createTestElement, getComponentSlotContent, removeTestElement, waitForComponent } from 'lithium-ui/test/utils'; 4 | 5 | describe('radio group element', () => { 6 | let testElement: HTMLElement; 7 | let component: LithiumRadioGroup; 8 | 9 | beforeEach(async () => { 10 | testElement = createTestElement(); 11 | testElement.innerHTML = ` 12 | 13 | hello world 14 | 15 | `; 16 | await waitForComponent('li-radio-group'); 17 | component = testElement.querySelector('li-radio-group'); 18 | }); 19 | 20 | afterEach(() => { 21 | removeTestElement(testElement); 22 | }); 23 | 24 | it('should render with appropriate slots', async () => { 25 | await componentIsStable(component); 26 | const slots = getComponentSlotContent(component); 27 | expect(slots.default).toBe('hello world'); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /projects/lithium/radio/radio-group.element.ts: -------------------------------------------------------------------------------- 1 | import { html, LitElement } from 'lit-element'; 2 | import { baseStyles, property, querySlotAll, registerElementSafely } from 'lithium-ui/common'; 3 | import { styles } from './radio-group.element.css'; 4 | import { LithiumRadio } from './radio.element'; 5 | 6 | /** 7 | * Radio Group, group element to associate a collection of radio inputs 8 | * 9 | * @noInheritDoc 10 | * @element li-radio-group 11 | * @slot default - Content slot for radio input 12 | */ 13 | // @dynamic 14 | export class LithiumRadioGroup extends LitElement { 15 | static get styles() { 16 | return [baseStyles, styles]; 17 | } 18 | 19 | /** Display radio elements inline */ 20 | @property({ type: Boolean }) inline: boolean; 21 | 22 | /** Name provides the name for each radio and will automatically associate all radios in element */ 23 | @property({ type: String }) name = ''; 24 | 25 | @querySlotAll('li-radio') private liRadioElements: NodeListOf; 26 | 27 | render() { 28 | return html` 29 |
30 | 31 |
32 | `; 33 | } 34 | 35 | connectedCallback() { 36 | super.connectedCallback(); 37 | Array.from(this.liRadioElements) 38 | .map(e => e.querySelector('input[type=radio]')) 39 | .forEach(radio => radio.setAttribute('name', this.name)); 40 | } 41 | 42 | /** internal */ 43 | _clearRadios() { 44 | this.liRadioElements.forEach(radio => radio.removeAttribute('checked')); 45 | } 46 | } 47 | 48 | registerElementSafely('li-radio-group', LithiumRadioGroup); 49 | 50 | declare global { 51 | interface HTMLElementTagNameMap { 52 | 'li-radio-group': LithiumRadioGroup; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /projects/lithium/radio/radio.element.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | --border: 1px solid var(--li-common-color-gray-300); 3 | --background: var(--li-common-color-white-100); 4 | --fill-background: var(--li-common-color-blue-100); 5 | --color-disabled: var(--li-common-color-gray-300); 6 | --color: inherit; 7 | display: block; 8 | position: relative; 9 | margin-bottom: var(--li-common-spacing-margin-bottom-small); 10 | } 11 | 12 | ::slotted(label) { 13 | padding-left: 1.75em; 14 | margin-right: 1em; 15 | cursor: pointer; 16 | } 17 | 18 | ::slotted([type='radio']) { 19 | position: absolute; 20 | left: -9999px; 21 | width: 0; 22 | height: 0; 23 | } 24 | 25 | .circle { 26 | position: absolute; 27 | display: inline-block; 28 | pointer-events: none; 29 | top: 0.2em; 30 | position: absolute; 31 | left: 0; 32 | top: 0.2em; 33 | width: 2em; 34 | height: 2em; 35 | border: var(--border); 36 | background: var(--background); 37 | border-radius: 50%; 38 | } 39 | 40 | .circle-fill { 41 | display: none; 42 | pointer-events: none; 43 | } 44 | 45 | :host([checked]) .circle-fill { 46 | background-color: var(--fill-background); 47 | display: block; 48 | position: absolute; 49 | width: 1.4em; 50 | height: 1.4em; 51 | top: 0.2em; 52 | left: 0.2em; 53 | z-index: 99; 54 | border-radius: 50%; 55 | } 56 | 57 | :host([disabled]) ::slotted(label) { 58 | color: var(--color-disabled) !important; 59 | cursor: not-allowed; 60 | } 61 | 62 | :host([focused]) ::slotted(label) { 63 | outline: var(--li-common-outline); 64 | box-shadow: var(--li-common-outline-shadow); 65 | } 66 | -------------------------------------------------------------------------------- /projects/lithium/sass-template.js: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | import { css } from 'lit-element'; 3 | export const styles = css`<% content %>`; -------------------------------------------------------------------------------- /projects/lithium/select/entrypoint.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "composite": true 5 | }, 6 | "references": [{ "path": "../common/entrypoint.tsconfig.json" }, { "path": "../input/entrypoint.tsconfig.json" }] 7 | } 8 | -------------------------------------------------------------------------------- /projects/lithium/select/index.ts: -------------------------------------------------------------------------------- 1 | export * from './select.element'; 2 | -------------------------------------------------------------------------------- /projects/lithium/select/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "sideEffects": true, 3 | "main": "./index.js", 4 | "module": "./index.js", 5 | "typings": "./index.d.ts", 6 | "name": "lithium-ui/select", 7 | "type": "module" 8 | } 9 | -------------------------------------------------------------------------------- /projects/lithium/select/select.element.spec.ts: -------------------------------------------------------------------------------- 1 | import 'lithium-ui/select'; 2 | import { LithiumSelect } from 'lithium-ui/select'; 3 | import { componentIsStable, createTestElement, getComponentSlotContent, removeTestElement, waitForComponent } from 'lithium-ui/test/utils'; 4 | 5 | describe('textarea element', () => { 6 | let testElement: HTMLElement; 7 | let component: LithiumSelect; 8 | 9 | beforeEach(async () => { 10 | testElement = createTestElement(); 11 | testElement.innerHTML = ` 12 | 13 | 14 | 19 | 20 | `; 21 | await waitForComponent('li-select'); 22 | component = testElement.querySelector('li-select'); 23 | }); 24 | 25 | afterEach(() => { 26 | removeTestElement(testElement); 27 | }); 28 | 29 | it('should render a select with appropriate slots', async () => { 30 | await componentIsStable(component); 31 | const slots = getComponentSlotContent(component); 32 | expect(slots.default.includes('Select an Option')).toBe(true); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /projects/lithium/select/select.element.ts: -------------------------------------------------------------------------------- 1 | import { property, registerElementSafely } from 'lithium-ui/common'; 2 | import { LithiumInput } from 'lithium-ui/input'; 3 | 4 | /** 5 | * Input, standard select input with accessibility and error enhancements. 6 | * 7 | * @element li-select 8 | * @slot default - Content slot select input 9 | * @cssprop --color 10 | * @cssprop --color-error 11 | * @cssprop --background 12 | * @cssprop --background-disabled 13 | * @cssprop --border-color 14 | * @cssprop --border-radius 15 | */ 16 | // @dynamic 17 | export class LithiumSelect extends LithiumInput { 18 | /** Set input in an error state */ 19 | @property({ type: Boolean }) error: boolean; 20 | } 21 | 22 | registerElementSafely('li-select', LithiumSelect); 23 | 24 | declare global { 25 | interface HTMLElementTagNameMap { 26 | 'li-select': LithiumSelect; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /projects/lithium/side-nav/entrypoint.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "composite": true 5 | }, 6 | "references": [ 7 | { "path": "../common/entrypoint.tsconfig.json" }, 8 | { "path": "../icon/entrypoint.tsconfig.json" }, 9 | { "path": "../icon-shapes/entrypoint.tsconfig.json" } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /projects/lithium/side-nav/index.ts: -------------------------------------------------------------------------------- 1 | export * from './side-nav.element'; 2 | -------------------------------------------------------------------------------- /projects/lithium/side-nav/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "sideEffects": true, 3 | "main": "./index.js", 4 | "module": "./index.js", 5 | "typings": "./index.d.ts", 6 | "name": "lithium-ui/side-nav", 7 | "type": "module" 8 | } 9 | -------------------------------------------------------------------------------- /projects/lithium/styles/_a11y.scss: -------------------------------------------------------------------------------- 1 | .li-sr-only { 2 | position: absolute; 3 | left: -10000px; 4 | top: auto; 5 | width: 1px; 6 | height: 1px; 7 | overflow: hidden; 8 | } 9 | -------------------------------------------------------------------------------- /projects/lithium/styles/_base.element.scss: -------------------------------------------------------------------------------- 1 | @import './variables'; 2 | @import './a11y'; 3 | @import './utils'; 4 | 5 | :host { 6 | font-size: var(--li-common-base-font-size, var(--li-global-base-font-size, 10px)) !important; 7 | box-sizing: border-box; 8 | } 9 | 10 | *, 11 | *:before, 12 | *:after { 13 | box-sizing: border-box; 14 | } 15 | 16 | slot { 17 | font-size: var(--li-common-font-size) !important; 18 | } 19 | -------------------------------------------------------------------------------- /projects/lithium/styles/_utils.scss: -------------------------------------------------------------------------------- 1 | .li-display-none { 2 | display: none !important; 3 | } 4 | -------------------------------------------------------------------------------- /projects/lithium/styles/_variables.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | /* colors */ 3 | --li-common-color-white-100: hsl(0, 0%, 100%); 4 | --li-common-color-gray-50: hsl(0, 0%, 97%); 5 | --li-common-color-gray-100: hsl(0, 0%, 95%); 6 | --li-common-color-gray-200: hsl(0, 0%, 89%); 7 | --li-common-color-gray-300: hsl(0, 0%, 80%); 8 | --li-common-color-gray-400: hsl(0, 0%, 24%); 9 | --li-common-color-gray-500: hsl(0, 0%, 18%); 10 | --li-common-color-gray-600: hsl(0, 0%, 16%); 11 | --li-common-color-gray-700: hsl(0, 0%, 12%); 12 | --li-common-color-blue-10: hsl(212, 100%, 97%); 13 | --li-common-color-blue-25: hsl(212, 100%, 93%); 14 | --li-common-color-blue-50: hsl(212, 83%, 59%); 15 | --li-common-color-blue-100: hsl(212, 66%, 48%); 16 | --li-common-color-green-100: hsl(120, 32%, 50%); 17 | --li-common-color-orange-100: hsl(44, 72%, 45%); 18 | --li-common-color-red-50: hsl(0, 78%, 53%); 19 | --li-common-color-red-100: hsl(0, 60%, 49%); 20 | 21 | /* shape */ 22 | --li-common-padding-md: 2.4em; 23 | --li-common-padding-md-negative: -2.4em; 24 | --li-common-border-radius: 0.3em; 25 | --li-common-outline: 1px solid var(--li-common-color-blue-50); 26 | --li-common-outline-shadow: 0 0 0.6em 0 var(--li-common-color-blue-100); 27 | --li-common-spacing-margin-bottom: var(--li-global-spacing-margin-bottom, 2.4em); 28 | --li-common-spacing-margin-bottom-small: var(--li-global-spacing-margin-bottom-small, 1.2em); 29 | --li-common-spacing-margin-bottom-large: var(--li-global-spacing-margin-bottom-large, 3.6em); 30 | --li-common-line-height: 2.4em; 31 | --li-common-font-size: 1.6em; 32 | --li-common-font-size-px: 16px; 33 | --li-common-font-color: var(--li-common-color-gray-500); 34 | } 35 | -------------------------------------------------------------------------------- /projects/lithium/switch/entrypoint.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "composite": true 5 | }, 6 | "references": [{ "path": "../common/entrypoint.tsconfig.json" }, { "path": "../checkbox/entrypoint.tsconfig.json" }] 7 | } 8 | -------------------------------------------------------------------------------- /projects/lithium/switch/index.ts: -------------------------------------------------------------------------------- 1 | export * from './switch.element'; 2 | -------------------------------------------------------------------------------- /projects/lithium/switch/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "sideEffects": true, 3 | "main": "./index.js", 4 | "module": "./index.js", 5 | "typings": "./index.d.ts", 6 | "name": "lithium-ui/switch", 7 | "type": "module" 8 | } 9 | -------------------------------------------------------------------------------- /projects/lithium/switch/switch.element.spec.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coryrylan/lithium/4e3bca83b1fa12c4572f3fed0f90fd52b1213392/projects/lithium/switch/switch.element.spec.ts -------------------------------------------------------------------------------- /projects/lithium/switch/switch.element.ts: -------------------------------------------------------------------------------- 1 | import { html } from 'lit-element'; 2 | import { LithiumCheckbox } from 'lithium-ui/checkbox'; 3 | import { baseStyles, property, registerElementSafely } from 'lithium-ui/common'; 4 | import { styles } from './switch.element.css'; 5 | 6 | /** 7 | * Switch, switch input with accessibility and error enhancements. 8 | * 9 | * @noInheritDoc 10 | * @element li-switch 11 | * @slot default - Content slot for checkbox input 12 | * @cssprop --color 13 | * @cssprop --color-disabled 14 | * @cssprop --border-color 15 | * @cssprop --background 16 | */ 17 | // @dynamic 18 | export class LithiumSwitch extends LithiumCheckbox { 19 | /** Set input in an error state */ 20 | @property({ type: Boolean }) error: boolean; 21 | 22 | static get styles() { 23 | return [baseStyles, styles]; 24 | } 25 | 26 | render() { 27 | return html` 28 |
29 | 30 | 31 | 32 |
33 | `; 34 | } 35 | 36 | switch() { 37 | this.checkbox.click(); 38 | this.checkbox.checked ? this.checkbox.setAttribute('checked', '') : this.checkbox.removeAttribute('checked'); 39 | } 40 | } 41 | 42 | registerElementSafely('li-switch', LithiumSwitch); 43 | 44 | declare global { 45 | interface HTMLElementTagNameMap { 46 | 'li-switch': LithiumSwitch; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /projects/lithium/tabs/entrypoint.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "composite": true 5 | }, 6 | "references": [{ "path": "../common/entrypoint.tsconfig.json" }] 7 | } 8 | -------------------------------------------------------------------------------- /projects/lithium/tabs/index.ts: -------------------------------------------------------------------------------- 1 | export * from './tabs.element'; 2 | export * from './tab.element'; 3 | export * from './tab-title.element'; 4 | -------------------------------------------------------------------------------- /projects/lithium/tabs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "sideEffects": true, 3 | "main": "./index.js", 4 | "module": "./index.js", 5 | "typings": "./index.d.ts", 6 | "name": "lithium-ui/tabs", 7 | "type": "module" 8 | } 9 | -------------------------------------------------------------------------------- /projects/lithium/tabs/tab-title.element.spec.ts: -------------------------------------------------------------------------------- 1 | import 'lithium-ui/tabs'; 2 | import { LithiumTabTitle } from 'lithium-ui/tabs'; 3 | import { componentIsStable, createTestElement, getComponentSlotContent, removeTestElement, waitForComponent } from 'lithium-ui/test/utils'; 4 | 5 | describe('card element', () => { 6 | let testElement: HTMLElement; 7 | let component: LithiumTabTitle; 8 | 9 | beforeEach(async () => { 10 | testElement = createTestElement(); 11 | testElement.innerHTML = ` 12 | 13 | hello world 14 | 15 | `; 16 | await waitForComponent('li-tab-title'); 17 | component = testElement.querySelector('li-tab-title'); 18 | }); 19 | 20 | afterEach(() => { 21 | removeTestElement(testElement); 22 | }); 23 | 24 | it('should render a title with appropriate slots', async () => { 25 | await componentIsStable(component); 26 | const slots = getComponentSlotContent(component); 27 | expect(slots.default).toBe('hello world'); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /projects/lithium/tabs/tab-title.element.ts: -------------------------------------------------------------------------------- 1 | import { html, LitElement } from 'lit-element'; 2 | import { registerElementSafely } from 'lithium-ui/common'; 3 | 4 | // @dynamic 5 | export class LithiumTabTitle extends LitElement { 6 | render() { 7 | return html` 8 | 9 | `; 10 | } 11 | } 12 | 13 | registerElementSafely('li-tab-title', LithiumTabTitle); 14 | 15 | declare global { 16 | interface HTMLElementTagNameMap { 17 | 'li-tab-title': LithiumTabTitle; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /projects/lithium/tabs/tab.element.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | --border-top: inherit; 3 | --background: inherit; 4 | } 5 | 6 | :host([aria-hidden]) .li-tab-content { 7 | display: none; 8 | } 9 | 10 | .li-tab-content { 11 | padding-top: 1.6em; 12 | overflow: visible; 13 | border-top: var(--tab-border-top); 14 | } 15 | -------------------------------------------------------------------------------- /projects/lithium/tabs/tab.element.spec.ts: -------------------------------------------------------------------------------- 1 | import 'lithium-ui/tabs'; 2 | import { LithiumTab } from 'lithium-ui/tabs'; 3 | import { componentIsStable, createTestElement, getComponentSlotContent, removeTestElement, waitForComponent } from 'lithium-ui/test/utils'; 4 | 5 | describe('card element', () => { 6 | let testElement: HTMLElement; 7 | let component: LithiumTab; 8 | 9 | beforeEach(async () => { 10 | testElement = createTestElement(); 11 | testElement.innerHTML = ` 12 | 13 | hello world 14 | 15 | `; 16 | await waitForComponent('li-tab'); 17 | component = testElement.querySelector('li-tab'); 18 | }); 19 | 20 | afterEach(() => { 21 | removeTestElement(testElement); 22 | }); 23 | 24 | it('should render tab content with appropriate slots', async () => { 25 | await componentIsStable(component); 26 | const slots = getComponentSlotContent(component); 27 | expect(slots.default).toBe('hello world'); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /projects/lithium/tabs/tab.element.ts: -------------------------------------------------------------------------------- 1 | import { html, LitElement } from 'lit-element'; 2 | import { baseStyles, registerElementSafely } from 'lithium-ui/common'; 3 | import { styles } from './tab.element.css'; 4 | 5 | // @dynamic 6 | export class LithiumTab extends LitElement { 7 | static get styles() { 8 | return [baseStyles, styles]; 9 | } 10 | 11 | render() { 12 | return html` 13 |
14 | 15 |
16 | `; 17 | } 18 | 19 | connectedCallback() { 20 | super.connectedCallback(); 21 | this.setAttribute('role', 'tabpanel'); 22 | } 23 | } 24 | 25 | registerElementSafely('li-tab', LithiumTab); 26 | 27 | declare global { 28 | interface HTMLElementTagNameMap { 29 | 'li-tab': LithiumTab; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /projects/lithium/tabs/tabs.element.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | --color: inherit; 3 | --button-background: inherit; 4 | --button-active-background: inherit; 5 | --button-active-border-bottom: 0.3em solid var(--li-common-color-blue-100); 6 | --tab-border-top: 1px solid var(--li-common-color-gray-300); 7 | --tab-background: inherit; 8 | } 9 | 10 | li-tab { 11 | --border-top: var(--tab-border-top); 12 | --background: var(--tab-background); 13 | } 14 | 15 | .li-tabs { 16 | display: block; 17 | } 18 | 19 | .li-tabs-nav { 20 | margin-bottom: 0; 21 | padding-left: 0; 22 | list-style: none; 23 | overflow-x: auto; 24 | overflow-y: visible; 25 | white-space: nowrap; 26 | 27 | &::before, 28 | &::after { 29 | content: ' '; 30 | display: table; 31 | clear: both; 32 | } 33 | 34 | button { 35 | position: relative; 36 | background: var(--button-background); 37 | margin-bottom: -1px; 38 | margin-right: 0.2em; 39 | cursor: pointer; 40 | padding: 1em 0.6em; 41 | line-height: 1.42857143; 42 | text-decoration: none; 43 | font-size: 1em; 44 | font-family: inherit; 45 | display: inline-block; 46 | min-width: 8em; 47 | text-align: center; 48 | color: var(--color); 49 | width: auto; 50 | border: 1px solid transparent; 51 | border-bottom: 0.3em solid transparent; 52 | 53 | &:nth-child(even) { 54 | border-right: 0; 55 | } 56 | 57 | &:nth-child(-n + 3) { 58 | border-bottom: 0.3em solid transparent; 59 | } 60 | 61 | &.active { 62 | background: var(--button-active-background); 63 | border-bottom: var(--button-active-border-bottom); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /projects/lithium/test-bundles/README.md: -------------------------------------------------------------------------------- 1 | # Test Bundles & Tree Shaking 2 | 3 | These tests check to ensure that Lithium properly can be consumed and 4 | tree shaken by the most commonly used module bundlers. 5 | 6 | ```javascript 7 | import 'lithium-ui/card'; 8 | ``` 9 | 10 | We should expect only the card component code to included in the final application 11 | and no other components are bundled. 12 | 13 | More complex scenarios we want to also tree shake at the symbol level such as when 14 | importing icons. 15 | 16 | ```javascript 17 | import 'lithium-ui/icon'; 18 | import { IconService, closeIcon, menuIcon } from 'lithium-ui/icon-shapes'; 19 | 20 | IconService.addIcons(closeIcon, menuIcon); 21 | ``` 22 | 23 | This example should only include the icon Web Component as well as only two of 24 | the many icons available in the final application bundle. 25 | 26 | To run these tests run the following commands 27 | 28 | ```bash 29 | npm run core:build 30 | npm run core:test:bundle 31 | ``` 32 | -------------------------------------------------------------------------------- /projects/lithium/test-bundles/bundlesize.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | { 4 | "path": "./dist/test-bundles/webpack.bundle.js", 5 | "maxSize": "10 kB" 6 | } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /projects/lithium/test-bundles/index.js: -------------------------------------------------------------------------------- 1 | import 'lithium-ui/card'; 2 | import 'lithium-ui/icon'; 3 | import { IconService, closeIcon, menuIcon } from 'lithium-ui/icon-shapes'; 4 | 5 | IconService.addIcons(closeIcon, menuIcon); -------------------------------------------------------------------------------- /projects/lithium/test-bundles/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | mode: 'production', 5 | entry: path.resolve(__dirname, './index.js'), 6 | resolve: { 7 | extensions: ['.js'], 8 | alias: { 9 | 'lithium-ui': path.resolve(__dirname, '../../../dist/lithium'), 10 | }, 11 | }, 12 | output: { 13 | filename: 'webpack.bundle.js', 14 | path: path.resolve(__dirname, '../../../dist/test-bundles'), 15 | }, 16 | }; 17 | -------------------------------------------------------------------------------- /projects/lithium/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import { getTestBed } from '@angular/core/testing'; 4 | import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; 5 | import 'zone.js/dist/zone'; 6 | import 'zone.js/dist/zone-testing'; 7 | 8 | declare const require: any; 9 | 10 | // First, initialize the Angular testing environment. 11 | getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting()); 12 | // Then we find all the tests. 13 | const context = require.context('./', true, /\.spec\.ts$/); 14 | // And load the modules. 15 | context.keys().map(context); 16 | -------------------------------------------------------------------------------- /projects/lithium/textarea/entrypoint.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.lib.json", 3 | "compilerOptions": { 4 | "composite": true 5 | }, 6 | "references": [{ "path": "../common/entrypoint.tsconfig.json" }, { "path": "../input/entrypoint.tsconfig.json" }] 7 | } 8 | -------------------------------------------------------------------------------- /projects/lithium/textarea/index.ts: -------------------------------------------------------------------------------- 1 | export * from './textarea.element'; 2 | -------------------------------------------------------------------------------- /projects/lithium/textarea/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "sideEffects": true, 3 | "main": "./index.js", 4 | "module": "./index.js", 5 | "typings": "./index.d.ts", 6 | "name": "lithium-ui/textarea", 7 | "type": "module" 8 | } 9 | -------------------------------------------------------------------------------- /projects/lithium/textarea/textarea.element.spec.ts: -------------------------------------------------------------------------------- 1 | import { componentIsStable, createTestElement, getComponentSlotContent, removeTestElement, waitForComponent } from 'lithium-ui/test/utils'; 2 | import 'lithium-ui/textarea'; 3 | import { LithiumTextArea } from 'lithium-ui/textarea'; 4 | 5 | describe('textarea element', () => { 6 | let testElement: HTMLElement; 7 | let component: LithiumTextArea; 8 | 9 | beforeEach(async () => { 10 | testElement = createTestElement(); 11 | testElement.innerHTML = ` 12 | 13 | 14 | 15 | 16 | `; 17 | await waitForComponent('li-textarea'); 18 | component = testElement.querySelector('li-textarea'); 19 | }); 20 | 21 | afterEach(() => { 22 | removeTestElement(testElement); 23 | }); 24 | 25 | it('should render a textarea with appropriate slots', async () => { 26 | await componentIsStable(component); 27 | const slots = getComponentSlotContent(component); 28 | expect(slots.default.includes('textarea label')).toBe(true); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /projects/lithium/textarea/textarea.element.ts: -------------------------------------------------------------------------------- 1 | import { property, registerElementSafely } from 'lithium-ui/common'; 2 | import { LithiumInput } from 'lithium-ui/input'; 3 | 4 | /** 5 | * Input, standard textarea with accessibility and error enhancements. 6 | * 7 | * @noInheritDoc 8 | * @element li-textarea 9 | * @slot default - Content slot for modal body 10 | * @cssprop --color 11 | * @cssprop --color-error 12 | * @cssprop --background 13 | * @cssprop --background-disabled 14 | * @cssprop --border-color 15 | * @cssprop --border-radius 16 | */ 17 | // @dynamic 18 | export class LithiumTextArea extends LithiumInput { 19 | /** Set input in an error state */ 20 | @property({ type: Boolean }) error: boolean; 21 | } 22 | 23 | registerElementSafely('li-textarea', LithiumTextArea); 24 | 25 | declare global { 26 | interface HTMLElementTagNameMap { 27 | 'li-textarea': LithiumTextArea; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /projects/lithium/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "module": "esnext", 5 | "moduleResolution": "node", 6 | "lib": ["es2017", "dom"], 7 | "experimentalDecorators": true, 8 | "allowSyntheticDefaultImports": true, 9 | "outDir": "../../dist/lithium", 10 | "declaration": true, 11 | "inlineSources": true, 12 | "types": ["jasmine"], 13 | "alwaysStrict": true, 14 | "noImplicitAny": true, 15 | "noImplicitReturns": true, 16 | "noImplicitThis": true, 17 | "noUnusedLocals": true, 18 | "noUnusedParameters": true, 19 | "strictFunctionTypes": true, 20 | "noFallthroughCasesInSwitch": true, 21 | "strictNullChecks": false, 22 | "sourceMap": true, 23 | "inlineSourceMap": false, 24 | "importHelpers": true, 25 | "composite": true, 26 | "baseUrl": "./", 27 | "rootDir": "./", 28 | "paths": { 29 | "lithium-ui/*": ["./*"] 30 | } 31 | }, 32 | "exclude": ["test.ts", "dist", "node_modules"], 33 | "references": [{ "path": "./common/entrypoint.tsconfig.json" }] 34 | } 35 | -------------------------------------------------------------------------------- /projects/lithium/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "types": [] 5 | }, 6 | "allowSyntheticDefaultImports": false, 7 | "exclude": ["**/test/*.ts", "test.ts", "**/*.spec.ts", "dist", "node_modules", "./storybook", "**/*.stories.ts"] 8 | } 9 | -------------------------------------------------------------------------------- /projects/lithium/tsconfig.project.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.lib.json", 3 | "compilerOptions": { 4 | "outDir": "../../dist/lithium", 5 | "rootDir": "./" 6 | }, 7 | "include": ["./"], 8 | "references": [ 9 | { "path": "./common/entrypoint.tsconfig.json" }, 10 | { "path": "./button/entrypoint.tsconfig.json" }, 11 | { "path": "./card/entrypoint.tsconfig.json" }, 12 | { "path": "./checkbox/entrypoint.tsconfig.json" }, 13 | { "path": "./code-example/entrypoint.tsconfig.json" }, 14 | { "path": "./datalist/entrypoint.tsconfig.json" }, 15 | { "path": "./datepicker/entrypoint.tsconfig.json" }, 16 | { "path": "./dropdown/entrypoint.tsconfig.json" }, 17 | { "path": "./form/entrypoint.tsconfig.json" }, 18 | { "path": "./icon/entrypoint.tsconfig.json" }, 19 | { "path": "./icon-shapes/entrypoint.tsconfig.json" }, 20 | { "path": "./input/entrypoint.tsconfig.json" }, 21 | { "path": "./message/entrypoint.tsconfig.json" }, 22 | { "path": "./modal/entrypoint.tsconfig.json" }, 23 | { "path": "./nav-bar/entrypoint.tsconfig.json" }, 24 | { "path": "./progress/entrypoint.tsconfig.json" }, 25 | { "path": "./radio/entrypoint.tsconfig.json" }, 26 | { "path": "./select/entrypoint.tsconfig.json" }, 27 | { "path": "./side-nav/entrypoint.tsconfig.json" }, 28 | { "path": "./switch/entrypoint.tsconfig.json" }, 29 | { "path": "./tabs/entrypoint.tsconfig.json" }, 30 | { "path": "./textarea/entrypoint.tsconfig.json" }, 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /projects/lithium/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "test.ts" 12 | ], 13 | "include": [ 14 | "**/*.spec.ts", 15 | "**/*.d.ts" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /projects/lithium/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tslint.json", 3 | "rules": { 4 | "no-barrel-imports": false, 5 | "import-blacklist": [true, {"lit-element": ["property"]}, "rxjs", "rxjs/operators", "@angular", "@angular/common", "@angular/core"] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/out-tsc", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "downlevelIteration": true, 9 | "experimentalDecorators": true, 10 | "module": "esnext", 11 | "moduleResolution": "node", 12 | "importHelpers": true, 13 | "target": "es2015", 14 | "typeRoots": [ 15 | "node_modules/@types" 16 | ], 17 | "lib": [ 18 | "es2018", 19 | "dom" 20 | ], 21 | "paths": { 22 | "lithium-ui/test/*": [ 23 | "projects/lithium/test/*" 24 | ], 25 | "lithium-ui": [ 26 | "dist/lithium" 27 | ], 28 | "lithium-ui/*": [ 29 | "dist/lithium/*" 30 | ] 31 | }, 32 | "alwaysStrict": true, 33 | "noImplicitAny": true, 34 | "noImplicitReturns": true, 35 | "noImplicitThis": true, 36 | "noUnusedLocals": true, 37 | "noUnusedParameters": true, 38 | "strictFunctionTypes": true, 39 | "noFallthroughCasesInSwitch": true 40 | }, 41 | "exclude": [ 42 | "dist" 43 | ], 44 | "angularCompilerOptions": { 45 | "fullTemplateTypeCheck": true, 46 | "strictInjectionParameters": true 47 | } 48 | } --------------------------------------------------------------------------------