Modernized!
This commit is contained in:
parent
fd75bb82e7
commit
ff11f79c51
|
@ -0,0 +1,29 @@
|
||||||
|
# EditorConfig helps developers define and maintain consistent
|
||||||
|
# coding styles between different editors and IDEs
|
||||||
|
# editorconfig.org
|
||||||
|
|
||||||
|
root = true
|
||||||
|
|
||||||
|
|
||||||
|
[*]
|
||||||
|
|
||||||
|
# Change these settings to your own preference
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
# We recommend you to keep these unchanged
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
|
[*.json]
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[*.{html,js,md}]
|
||||||
|
block_comment_start = /**
|
||||||
|
block_comment = *
|
||||||
|
block_comment_end = */
|
|
@ -0,0 +1,8 @@
|
||||||
|
# don't ever lint node_modules
|
||||||
|
node_modules
|
||||||
|
# don't lint build output (make sure it's set to your correct build folder name)
|
||||||
|
dist
|
||||||
|
# don't lint nyc coverage output
|
||||||
|
coverage
|
||||||
|
src/locale-codes.ts
|
||||||
|
storybook-static/
|
|
@ -1,58 +1,36 @@
|
||||||
{
|
{
|
||||||
"parser": "@typescript-eslint/parser",
|
|
||||||
"plugins": ["@typescript-eslint", "eslint-plugin-import", "prettier"],
|
|
||||||
"root": true,
|
|
||||||
"env": {
|
"env": {
|
||||||
"browser": true,
|
"browser": true,
|
||||||
"es2021": true
|
"es2021": true
|
||||||
},
|
},
|
||||||
"extends": ["airbnb", "plugin:@typescript-eslint/recommended", "prettier"],
|
"extends": [
|
||||||
|
"eslint:recommended",
|
||||||
|
"plugin:@typescript-eslint/recommended",
|
||||||
|
"plugin:lit/recommended",
|
||||||
|
"plugin:custom-elements/recommended",
|
||||||
|
"plugin:storybook/recommended"
|
||||||
|
],
|
||||||
|
"parser": "@typescript-eslint/parser",
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"project": ["tsconfig.json"],
|
"ecmaVersion": 12,
|
||||||
"ecmaVersion": 2020,
|
|
||||||
"sourceType": "module"
|
"sourceType": "module"
|
||||||
},
|
},
|
||||||
|
"plugins": ["@typescript-eslint", "lit", "custom-elements"],
|
||||||
|
"ignorePatterns": ["demo/**", "stories/**"],
|
||||||
"rules": {
|
"rules": {
|
||||||
"no-await-in-loop": "off",
|
"indent": "off",
|
||||||
"no-use-before-define": "off",
|
"linebreak-style": ["error", "unix"],
|
||||||
"no-nested-ternary": "off",
|
"quotes": ["error", "double", { "avoidEscape": true }],
|
||||||
"@typescript-eslint/no-use-before-define": ["error"],
|
"semi": ["error", "always"],
|
||||||
"@typescript-eslint/explicit-function-return-type": "off",
|
"@typescript-eslint/ban-ts-comment": "off",
|
||||||
"@typescript-eslint/no-unused-vars": "off",
|
"no-unused-vars": "off",
|
||||||
"import/extensions": "off",
|
"@typescript-eslint/no-unused-vars": [
|
||||||
"import/prefer-default-export": "off",
|
"error",
|
||||||
"@typescript-eslint/ban-types": "warn",
|
{
|
||||||
"@typescript-eslint/no-use-before-define": "warn",
|
"argsIgnorePattern": "^_",
|
||||||
"arrow-body-style": "warn",
|
"varsIgnorePattern": "^_",
|
||||||
"camelcase": "warn",
|
"caughtErrorsIgnorePattern": "^_"
|
||||||
"dot-notation": "warn",
|
|
||||||
"eqeqeq": "warn",
|
|
||||||
"import/first": "warn",
|
|
||||||
"import/newline-after-import": "warn",
|
|
||||||
"import/no-extraneous-dependencies": "warn",
|
|
||||||
"import/order": "warn",
|
|
||||||
"no-else-return": "warn",
|
|
||||||
"no-param-reassign": "warn",
|
|
||||||
"no-return-assign": "warn",
|
|
||||||
"no-sequences": "warn",
|
|
||||||
"no-shadow": "off",
|
|
||||||
"@typescript-eslint/no-shadow": ["warn"],
|
|
||||||
"no-underscore-dangle": "warn",
|
|
||||||
"no-unneeded-ternary": "warn",
|
|
||||||
"object-shorthand": "warn",
|
|
||||||
"prefer-arrow-callback": "warn",
|
|
||||||
"prefer-const": "warn",
|
|
||||||
"prefer-destructuring": "warn",
|
|
||||||
"prefer-template": "warn"
|
|
||||||
},
|
|
||||||
"settings": {
|
|
||||||
"import/resolver": {
|
|
||||||
"node": {
|
|
||||||
"extensions": [".js", ".ts"]
|
|
||||||
},
|
|
||||||
"typescript": {
|
|
||||||
"project": "./tsconfig.json"
|
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
"env": {
|
||||||
|
"browser": true,
|
||||||
|
"es2021": true
|
||||||
|
},
|
||||||
|
"extends": [
|
||||||
|
"eslint:recommended",
|
||||||
|
"plugin:@typescript-eslint/recommended",
|
||||||
|
"plugin:lit/recommended",
|
||||||
|
"plugin:custom-elements/recommended",
|
||||||
|
"plugin:storybook/recommended",
|
||||||
|
"plugin:sonarjs/recommended"
|
||||||
|
],
|
||||||
|
"parser": "@typescript-eslint/parser",
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaVersion": 12,
|
||||||
|
"sourceType": "module"
|
||||||
|
},
|
||||||
|
"plugins": ["@typescript-eslint", "lit", "custom-elements", "sonarjs"],
|
||||||
|
"rules": {
|
||||||
|
"indent": "off",
|
||||||
|
"linebreak-style": ["error", "unix"],
|
||||||
|
"quotes": ["error", "double", { "avoidEscape": true }],
|
||||||
|
"semi": ["error", "always"],
|
||||||
|
"@typescript-eslint/ban-ts-comment": "off",
|
||||||
|
"sonarjs/cognitive-complexity": ["error", 9],
|
||||||
|
"sonarjs/no-nested-template-literals": "off"
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,25 @@
|
||||||
*#
|
## editors
|
||||||
.#*
|
/.idea
|
||||||
*~
|
/.vscode
|
||||||
node_modules
|
|
||||||
build
|
## system files
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
## npm
|
||||||
|
/node_modules/
|
||||||
|
/npm-debug.log
|
||||||
|
|
||||||
|
## testing
|
||||||
|
/coverage/
|
||||||
|
|
||||||
|
## temp folders
|
||||||
|
/.tmp/
|
||||||
|
|
||||||
|
# build
|
||||||
|
/_site/
|
||||||
|
/dist/
|
||||||
|
/out-tsc/
|
||||||
|
/build-modern/
|
||||||
|
|
||||||
|
storybook-static
|
||||||
|
custom-elements.json
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
repos:
|
|
||||||
- repo: https://github.com/pre-commit/mirrors-prettier
|
|
||||||
rev: "v2.4.1" # Use the sha / tag you want to point at
|
|
||||||
hooks:
|
|
||||||
- id: prettier
|
|
||||||
exclude: "index.html"
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
# don't ever lint node_modules
|
||||||
|
node_modules
|
||||||
|
# don't lint build output (make sure it's set to your correct build folder name)
|
||||||
|
dist
|
||||||
|
# don't lint nyc coverage output
|
||||||
|
coverage
|
||||||
|
# Import order matters
|
||||||
|
poly.ts
|
||||||
|
src/locale-codes.ts
|
||||||
|
src/locales/
|
||||||
|
storybook-static/
|
|
@ -1,8 +0,0 @@
|
||||||
{
|
|
||||||
"trailingComma": "es5",
|
|
||||||
"printWidth": 110,
|
|
||||||
"tabWidth": 4,
|
|
||||||
"useTabs": false,
|
|
||||||
"semi": true,
|
|
||||||
"singleQuote": false
|
|
||||||
}
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"arrowParens": "always",
|
||||||
|
"bracketSpacing": true,
|
||||||
|
"embeddedLanguageFormatting": "auto",
|
||||||
|
"htmlWhitespaceSensitivity": "css",
|
||||||
|
"insertPragma": false,
|
||||||
|
"jsxSingleQuote": false,
|
||||||
|
"printWidth": 100,
|
||||||
|
"proseWrap": "preserve",
|
||||||
|
"quoteProps": "consistent",
|
||||||
|
"requirePragma": false,
|
||||||
|
"semi": true,
|
||||||
|
"singleQuote": false,
|
||||||
|
"tabWidth": 4,
|
||||||
|
"trailingComma": "all",
|
||||||
|
"useTabs": false,
|
||||||
|
"vueIndentScriptAndStyle": false,
|
||||||
|
"plugins": ["@trivago/prettier-plugin-sort-imports"],
|
||||||
|
"importOrder": ["^(@?)lit(.*)$", "\\.css$", "^@goauthentik/api$", "^[./]"],
|
||||||
|
"importOrderSeparation": true,
|
||||||
|
"importOrderSortSpecifiers": true,
|
||||||
|
"importOrderParserPlugins": ["typescript", "classProperties", "decorators-legacy"]
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = {
|
||||||
|
stories: ['../dist/stories/**/*.stories.{js,md,mdx}'],
|
||||||
|
};
|
|
@ -0,0 +1,8 @@
|
||||||
|
import { storybookPlugin } from '@web/dev-server-storybook';
|
||||||
|
import baseConfig from '../web-dev-server.config.mjs';
|
||||||
|
|
||||||
|
export default /** @type {import('@web/dev-server').DevServerConfig} */ ({
|
||||||
|
...baseConfig,
|
||||||
|
open: '/',
|
||||||
|
plugins: [storybookPlugin({ type: 'web-components' }), ...baseConfig.plugins],
|
||||||
|
});
|
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2023 pendor-clock
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
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.
|
107
LICENSE.md
107
LICENSE.md
|
@ -1,83 +1,85 @@
|
||||||
# Mozilla Public License Version 2.0
|
Mozilla Public License Version 2.0
|
||||||
|
==================================
|
||||||
|
|
||||||
### 1. Definitions
|
### 1. Definitions
|
||||||
|
|
||||||
**1.1. “Contributor”**
|
**1.1. “Contributor”**
|
||||||
means each individual or legal entity that creates, contributes to
|
means each individual or legal entity that creates, contributes to
|
||||||
the creation of, or owns Covered Software.
|
the creation of, or owns Covered Software.
|
||||||
|
|
||||||
**1.2. “Contributor Version”**
|
**1.2. “Contributor Version”**
|
||||||
means the combination of the Contributions of others (if any) used
|
means the combination of the Contributions of others (if any) used
|
||||||
by a Contributor and that particular Contributor's Contribution.
|
by a Contributor and that particular Contributor's Contribution.
|
||||||
|
|
||||||
**1.3. “Contribution”**
|
**1.3. “Contribution”**
|
||||||
means Covered Software of a particular Contributor.
|
means Covered Software of a particular Contributor.
|
||||||
|
|
||||||
**1.4. “Covered Software”**
|
**1.4. “Covered Software”**
|
||||||
means Source Code Form to which the initial Contributor has attached
|
means Source Code Form to which the initial Contributor has attached
|
||||||
the notice in Exhibit A, the Executable Form of such Source Code
|
the notice in Exhibit A, the Executable Form of such Source Code
|
||||||
Form, and Modifications of such Source Code Form, in each case
|
Form, and Modifications of such Source Code Form, in each case
|
||||||
including portions thereof.
|
including portions thereof.
|
||||||
|
|
||||||
**1.5. “Incompatible With Secondary Licenses”**
|
**1.5. “Incompatible With Secondary Licenses”**
|
||||||
means
|
means
|
||||||
|
|
||||||
- **(a)** that the initial Contributor has attached the notice described
|
* **(a)** that the initial Contributor has attached the notice described
|
||||||
in Exhibit B to the Covered Software; or
|
in Exhibit B to the Covered Software; or
|
||||||
- **(b)** that the Covered Software was made available under the terms of
|
* **(b)** that the Covered Software was made available under the terms of
|
||||||
version 1.1 or earlier of the License, but not also under the
|
version 1.1 or earlier of the License, but not also under the
|
||||||
terms of a Secondary License.
|
terms of a Secondary License.
|
||||||
|
|
||||||
**1.6. “Executable Form”**
|
**1.6. “Executable Form”**
|
||||||
means any form of the work other than Source Code Form.
|
means any form of the work other than Source Code Form.
|
||||||
|
|
||||||
**1.7. “Larger Work”**
|
**1.7. “Larger Work”**
|
||||||
means a work that combines Covered Software with other material, in
|
means a work that combines Covered Software with other material, in
|
||||||
a separate file or files, that is not Covered Software.
|
a separate file or files, that is not Covered Software.
|
||||||
|
|
||||||
**1.8. “License”**
|
**1.8. “License”**
|
||||||
means this document.
|
means this document.
|
||||||
|
|
||||||
**1.9. “Licensable”**
|
**1.9. “Licensable”**
|
||||||
means having the right to grant, to the maximum extent possible,
|
means having the right to grant, to the maximum extent possible,
|
||||||
whether at the time of the initial grant or subsequently, any and
|
whether at the time of the initial grant or subsequently, any and
|
||||||
all of the rights conveyed by this License.
|
all of the rights conveyed by this License.
|
||||||
|
|
||||||
**1.10. “Modifications”**
|
**1.10. “Modifications”**
|
||||||
means any of the following:
|
means any of the following:
|
||||||
|
|
||||||
- **(a)** any file in Source Code Form that results from an addition to,
|
* **(a)** any file in Source Code Form that results from an addition to,
|
||||||
deletion from, or modification of the contents of Covered
|
deletion from, or modification of the contents of Covered
|
||||||
Software; or
|
Software; or
|
||||||
- **(b)** any new file in Source Code Form that contains any Covered
|
* **(b)** any new file in Source Code Form that contains any Covered
|
||||||
Software.
|
Software.
|
||||||
|
|
||||||
**1.11. “Patent Claims” of a Contributor**
|
**1.11. “Patent Claims” of a Contributor**
|
||||||
means any patent claim(s), including without limitation, method,
|
means any patent claim(s), including without limitation, method,
|
||||||
process, and apparatus claims, in any patent Licensable by such
|
process, and apparatus claims, in any patent Licensable by such
|
||||||
Contributor that would be infringed, but for the grant of the
|
Contributor that would be infringed, but for the grant of the
|
||||||
License, by the making, using, selling, offering for sale, having
|
License, by the making, using, selling, offering for sale, having
|
||||||
made, import, or transfer of either its Contributions or its
|
made, import, or transfer of either its Contributions or its
|
||||||
Contributor Version.
|
Contributor Version.
|
||||||
|
|
||||||
**1.12. “Secondary License”**
|
**1.12. “Secondary License”**
|
||||||
means either the GNU General Public License, Version 2.0, the GNU
|
means either the GNU General Public License, Version 2.0, the GNU
|
||||||
Lesser General Public License, Version 2.1, the GNU Affero General
|
Lesser General Public License, Version 2.1, the GNU Affero General
|
||||||
Public License, Version 3.0, or any later versions of those
|
Public License, Version 3.0, or any later versions of those
|
||||||
licenses.
|
licenses.
|
||||||
|
|
||||||
**1.13. “Source Code Form”**
|
**1.13. “Source Code Form”**
|
||||||
means the form of the work preferred for making modifications.
|
means the form of the work preferred for making modifications.
|
||||||
|
|
||||||
**1.14. “You” (or “Your”)**
|
**1.14. “You” (or “Your”)**
|
||||||
means an individual or a legal entity exercising rights under this
|
means an individual or a legal entity exercising rights under this
|
||||||
License. For legal entities, “You” includes any entity that
|
License. For legal entities, “You” includes any entity that
|
||||||
controls, is controlled by, or is under common control with You. For
|
controls, is controlled by, or is under common control with You. For
|
||||||
purposes of this definition, “control” means **(a)** the power, direct
|
purposes of this definition, “control” means **(a)** the power, direct
|
||||||
or indirect, to cause the direction or management of such entity,
|
or indirect, to cause the direction or management of such entity,
|
||||||
whether by contract or otherwise, or **(b)** ownership of more than
|
whether by contract or otherwise, or **(b)** ownership of more than
|
||||||
fifty percent (50%) of the outstanding shares or beneficial
|
fifty percent (50%) of the outstanding shares or beneficial
|
||||||
ownership of such entity.
|
ownership of such entity.
|
||||||
|
|
||||||
|
|
||||||
### 2. License Grants and Conditions
|
### 2. License Grants and Conditions
|
||||||
|
|
||||||
|
@ -86,12 +88,12 @@ ownership of such entity.
|
||||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||||
non-exclusive license:
|
non-exclusive license:
|
||||||
|
|
||||||
- **(a)** under intellectual property rights (other than patent or trademark)
|
* **(a)** under intellectual property rights (other than patent or trademark)
|
||||||
Licensable by such Contributor to use, reproduce, make available,
|
Licensable by such Contributor to use, reproduce, make available,
|
||||||
modify, display, perform, distribute, and otherwise exploit its
|
modify, display, perform, distribute, and otherwise exploit its
|
||||||
Contributions, either on an unmodified basis, with Modifications, or
|
Contributions, either on an unmodified basis, with Modifications, or
|
||||||
as part of a Larger Work; and
|
as part of a Larger Work; and
|
||||||
- **(b)** under Patent Claims of such Contributor to make, use, sell, offer
|
* **(b)** under Patent Claims of such Contributor to make, use, sell, offer
|
||||||
for sale, have made, import, and otherwise transfer either its
|
for sale, have made, import, and otherwise transfer either its
|
||||||
Contributions or its Contributor Version.
|
Contributions or its Contributor Version.
|
||||||
|
|
||||||
|
@ -109,13 +111,13 @@ distribution or licensing of Covered Software under this License.
|
||||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||||
Contributor:
|
Contributor:
|
||||||
|
|
||||||
- **(a)** for any code that a Contributor has removed from Covered Software;
|
* **(a)** for any code that a Contributor has removed from Covered Software;
|
||||||
or
|
or
|
||||||
- **(b)** for infringements caused by: **(i)** Your and any other third party's
|
* **(b)** for infringements caused by: **(i)** Your and any other third party's
|
||||||
modifications of Covered Software, or **(ii)** the combination of its
|
modifications of Covered Software, or **(ii)** the combination of its
|
||||||
Contributions with other software (except as part of its Contributor
|
Contributions with other software (except as part of its Contributor
|
||||||
Version); or
|
Version); or
|
||||||
- **(c)** under Patent Claims infringed by Covered Software in the absence of
|
* **(c)** under Patent Claims infringed by Covered Software in the absence of
|
||||||
its Contributions.
|
its Contributions.
|
||||||
|
|
||||||
This License does not grant any rights in the trademarks, service marks,
|
This License does not grant any rights in the trademarks, service marks,
|
||||||
|
@ -146,6 +148,7 @@ equivalents.
|
||||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
|
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
|
||||||
in Section 2.1.
|
in Section 2.1.
|
||||||
|
|
||||||
|
|
||||||
### 3. Responsibilities
|
### 3. Responsibilities
|
||||||
|
|
||||||
#### 3.1. Distribution of Source Form
|
#### 3.1. Distribution of Source Form
|
||||||
|
@ -162,13 +165,13 @@ Form.
|
||||||
|
|
||||||
If You distribute Covered Software in Executable Form then:
|
If You distribute Covered Software in Executable Form then:
|
||||||
|
|
||||||
- **(a)** such Covered Software must also be made available in Source Code
|
* **(a)** such Covered Software must also be made available in Source Code
|
||||||
Form, as described in Section 3.1, and You must inform recipients of
|
Form, as described in Section 3.1, and You must inform recipients of
|
||||||
the Executable Form how they can obtain a copy of such Source Code
|
the Executable Form how they can obtain a copy of such Source Code
|
||||||
Form by reasonable means in a timely manner, at a charge no more
|
Form by reasonable means in a timely manner, at a charge no more
|
||||||
than the cost of distribution to the recipient; and
|
than the cost of distribution to the recipient; and
|
||||||
|
|
||||||
- **(b)** You may distribute such Executable Form under the terms of this
|
* **(b)** You may distribute such Executable Form under the terms of this
|
||||||
License, or sublicense it under different terms, provided that the
|
License, or sublicense it under different terms, provided that the
|
||||||
license for the Executable Form does not attempt to limit or alter
|
license for the Executable Form does not attempt to limit or alter
|
||||||
the recipients' rights in the Source Code Form under this License.
|
the recipients' rights in the Source Code Form under this License.
|
||||||
|
@ -207,6 +210,7 @@ indemnity or liability terms You offer. You may include additional
|
||||||
disclaimers of warranty and limitations of liability specific to any
|
disclaimers of warranty and limitations of liability specific to any
|
||||||
jurisdiction.
|
jurisdiction.
|
||||||
|
|
||||||
|
|
||||||
### 4. Inability to Comply Due to Statute or Regulation
|
### 4. Inability to Comply Due to Statute or Regulation
|
||||||
|
|
||||||
If it is impossible for You to comply with any of the terms of this
|
If it is impossible for You to comply with any of the terms of this
|
||||||
|
@ -219,6 +223,7 @@ Software under this License. Except to the extent prohibited by statute
|
||||||
or regulation, such description must be sufficiently detailed for a
|
or regulation, such description must be sufficiently detailed for a
|
||||||
recipient of ordinary skill to be able to understand it.
|
recipient of ordinary skill to be able to understand it.
|
||||||
|
|
||||||
|
|
||||||
### 5. Termination
|
### 5. Termination
|
||||||
|
|
||||||
**5.1.** The rights granted under this License will terminate automatically
|
**5.1.** The rights granted under this License will terminate automatically
|
||||||
|
@ -247,6 +252,7 @@ end user license agreements (excluding distributors and resellers) which
|
||||||
have been validly granted by You or Your distributors under this License
|
have been validly granted by You or Your distributors under this License
|
||||||
prior to termination shall survive termination.
|
prior to termination shall survive termination.
|
||||||
|
|
||||||
|
|
||||||
### 6. Disclaimer of Warranty
|
### 6. Disclaimer of Warranty
|
||||||
|
|
||||||
> Covered Software is provided under this License on an “as is”
|
> Covered Software is provided under this License on an “as is”
|
||||||
|
@ -279,6 +285,7 @@ prior to termination shall survive termination.
|
||||||
> incidental or consequential damages, so this exclusion and
|
> incidental or consequential damages, so this exclusion and
|
||||||
> limitation may not apply to You.
|
> limitation may not apply to You.
|
||||||
|
|
||||||
|
|
||||||
### 8. Litigation
|
### 8. Litigation
|
||||||
|
|
||||||
Any litigation relating to this License may be brought only in the
|
Any litigation relating to this License may be brought only in the
|
||||||
|
@ -288,6 +295,7 @@ jurisdiction, without reference to its conflict-of-law provisions.
|
||||||
Nothing in this Section shall prevent a party's ability to bring
|
Nothing in this Section shall prevent a party's ability to bring
|
||||||
cross-claims or counter-claims.
|
cross-claims or counter-claims.
|
||||||
|
|
||||||
|
|
||||||
### 9. Miscellaneous
|
### 9. Miscellaneous
|
||||||
|
|
||||||
This License represents the complete agreement concerning the subject
|
This License represents the complete agreement concerning the subject
|
||||||
|
@ -297,6 +305,7 @@ necessary to make it enforceable. Any law or regulation which provides
|
||||||
that the language of a contract shall be construed against the drafter
|
that the language of a contract shall be construed against the drafter
|
||||||
shall not be used to construe this License against a Contributor.
|
shall not be used to construe this License against a Contributor.
|
||||||
|
|
||||||
|
|
||||||
### 10. Versions of the License
|
### 10. Versions of the License
|
||||||
|
|
||||||
#### 10.1. New Versions
|
#### 10.1. New Versions
|
||||||
|
|
63
README.md
63
README.md
|
@ -1,43 +1,34 @@
|
||||||
# The Pendor Clock
|
# \<pendor-clock>
|
||||||
|
|
||||||
This is code that's been around since 1996 or so, and is one of the
|
Way back at the dawn of the Internet, I started writing (and sometimes still write) a long-running
|
||||||
three first Javascript programs I ever wrote. It's just the "time of
|
adult space opera serial called [The Journal Entries](https://pendorwright.com/journals). One of the
|
||||||
day" counter for the fictional world that's the setting of my
|
conceits of the series in that the distant world of Pendor was built and terraformed to have a
|
||||||
long-running [space opera
|
30-hour day, but its years and Terra's years are of exactly the same length. A 30-hour day has a
|
||||||
series](https://www.pendorwright.com/journals/). It has its own
|
different calendar, and one of the very first [Java
|
||||||
calendar, and unlike Star Trek, I had in mind what the "star dates"
|
applets](https://en.wikipedia.org/wiki/Java_applet) (remember those?) I wrote was a clock that
|
||||||
would mean early on.
|
showed the time of day on Pendor.
|
||||||
|
|
||||||
# Motivation
|
This is the Pendorclock, but modernized into a custom Web Component, capable of running in any
|
||||||
|
browser without your needing to do anything at all to make it work correctly. It will load its own
|
||||||
|
font (Google Audiowide) and run anywhere you want. The font is not currently customizable without a
|
||||||
|
rebuild, but the following CSS Custom Attributes are exposed and you're free to change any of them:
|
||||||
|
|
||||||
This is a slightly modernized version, just to see what it would be
|
``` JavaScript
|
||||||
like to write this in 2021. The answer is that not much has changed;
|
background-color: var(--pendorclock-background-color, #000030);
|
||||||
the code runs just fine, although `getYear()` has been deprecated,
|
color: var(--pendorclock-color, #ffffff);
|
||||||
replaced by `.geUTCFullYear()`. The syntax of 2021 Javascript is a lot
|
font-size: var(--pendorclock-font-size, --default-font-size);
|
||||||
nicer than 1996, although there is a limit to how much density one can
|
line-height: var(--pendorclock-line-height, 1.35);
|
||||||
achieve when it's a lot of fiddly calculations around converting
|
font-weight: var(--pendorclock-font-weight, 700);
|
||||||
human-readable dates into Pendorian-readable ones.
|
|
||||||
|
|
||||||
What this project _really_ involves is preserving the basic elements
|
|
||||||
of prettier, eslint, vitejs, and typescript that I routinely use these
|
|
||||||
days as the basis of my Javascript work. Most of the configuration
|
|
||||||
files are short, as you'd expect from a vanilla javascript project
|
|
||||||
with a single source file and no framework, but they do include things
|
|
||||||
like sourcemap inclusion, minification, and using rollup to generate
|
|
||||||
proper EcmaScript-6.
|
|
||||||
|
|
||||||
# Running it
|
|
||||||
|
|
||||||
Really? Okay:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ npm install
|
|
||||||
$ npm run dev
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The demo will be on port 3000 by default.
|
This is mostly my set-up these days, complete with the hard-core `lint:hard`, Codespell, and
|
||||||
|
automatic Prettier.
|
||||||
|
|
||||||
|
## LICENSE
|
||||||
|
|
||||||
|
The Pendorwright Clock is Copyright [Elf M. Sternberg](https://elfsternberg.com) (c) 2023, and
|
||||||
|
licensed with the Mozilla Public License vers. 2.0. A copy of the license file is included in the
|
||||||
|
root folder.
|
||||||
|
|
||||||
|
|
||||||
# License
|
|
||||||
|
|
||||||
This code is released under the Mozilla 2.0 Public License. A copy of
|
|
||||||
the License File is included in this folder.
|
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en-GB">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background: #fafafa;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="demo"></div>
|
||||||
|
|
||||||
|
<script type="module">
|
||||||
|
import { html, render } from 'lit';
|
||||||
|
import '../dist/src/pendor-clock.js';
|
||||||
|
render(
|
||||||
|
html`
|
||||||
|
<pendor-clock>
|
||||||
|
</pendor-clock>
|
||||||
|
`,
|
||||||
|
document.querySelector('#demo')
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
15
index.html
15
index.html
|
@ -1,15 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>Pendordate Testbed</title>
|
|
||||||
<meta http-equiv="X-UI-Compatible" content="ie-edge" />
|
|
||||||
<meta property="og:type" content="website" />
|
|
||||||
<meta name="theme-color" content="#000000" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<p>The Date on Pendor is: <span id="pendordate" /></p>
|
|
||||||
<script type="module" src="/src/index.ts"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
File diff suppressed because it is too large
Load Diff
114
package.json
114
package.json
|
@ -1,33 +1,95 @@
|
||||||
{
|
{
|
||||||
"name": "pendorclock",
|
"name": "pendor-clock",
|
||||||
"version": "1.0.0",
|
"description": "Webcomponent pendor-clock following open-wc recommendations",
|
||||||
"description": "The Pendor Clock, updated for 2021",
|
"license": "MIT",
|
||||||
"main": "build/index.js",
|
"author": "pendor-clock",
|
||||||
"scripts": {
|
"version": "0.0.0",
|
||||||
"build": "vite build",
|
"type": "module",
|
||||||
"lint": "eslint",
|
"main": "dist/src/index.js",
|
||||||
"dev": "vite -m development",
|
"module": "dist/src/index.js",
|
||||||
"test": "jest"
|
"exports": {
|
||||||
|
".": "./dist/src/index.js",
|
||||||
|
"./pendor-clock.js": "./dist/src/pendor-clock.js"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"analyze": "cem analyze --litelement",
|
||||||
|
"start": "tsc && concurrently -k -r \"tsc --watch --preserveWatchOutput\" \"wds\"",
|
||||||
|
"build": "tsc && npm run analyze -- --exclude dist",
|
||||||
|
"prepublish": "tsc && npm run analyze -- --exclude dist",
|
||||||
|
"bundle": "npm run build && rollup -c rollup.conf.js && rm -fr build-modern/node_modules",
|
||||||
|
"lint": "eslint --ext .ts,.html ./src --ignore-path .gitignore && prettier \"**/*.ts\" --config .prettierrc.json --check --ignore-path .gitignore",
|
||||||
|
"lint:hard": "eslint --ext .ts,.html --config ./.eslintrc.precommit.json ./src/ --ignore-path .gitignore && prettier --config .prettierrc.json \"**/*.ts\" --check --ignore-path .gitignore",
|
||||||
|
"format": "eslint --ext .ts,.html . --fix --ignore-path .gitignore && prettier \"**/*.ts\" --config .prettierrc.json --write --ignore-path .gitignore",
|
||||||
|
"lint:spelling": "codespell -D - ./src -s",
|
||||||
|
"storybook": "tsc && npm run analyze -- --exclude dist && concurrently -k -r \"tsc --watch --preserveWatchOutput\" \"wds -c .storybook/server.mjs\"",
|
||||||
|
"storybook:build": "tsc && npm run analyze -- --exclude dist && build-storybook"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"lit": "^2.0.2"
|
||||||
},
|
},
|
||||||
"author": "Elf M. Sternberg <elf.sternberg@gmail.com>",
|
|
||||||
"license": "MPL-2.0",
|
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^27.0.2",
|
"@custom-elements-manifest/analyzer": "^0.4.17",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
"@open-wc/eslint-config": "^9.2.1",
|
||||||
"@typescript-eslint/parser": "^5.4.0",
|
"@rollup/plugin-node-resolve": "^15.2.2",
|
||||||
"eslint": "^8.2.0",
|
"@trivago/prettier-plugin-sort-imports": "^4.2.0",
|
||||||
"eslint-config-airbnb": "^19.0.0",
|
"@typescript-eslint/eslint-plugin": "^5.48.0",
|
||||||
|
"@typescript-eslint/parser": "^5.48.0",
|
||||||
|
"@web/dev-server": "^0.1.34",
|
||||||
|
"@web/dev-server-storybook": "^0.5.4",
|
||||||
|
"concurrently": "^5.3.0",
|
||||||
|
"eslint": "^8.31.0",
|
||||||
"eslint-config-prettier": "^8.3.0",
|
"eslint-config-prettier": "^8.3.0",
|
||||||
"eslint-import-resolver-typescript": "^2.5.0",
|
"eslint-plugin-custom-elements": "^0.0.8",
|
||||||
"eslint-plugin-import": "^2.25.3",
|
"eslint-plugin-sonarjs": "^0.21.0",
|
||||||
"eslint-plugin-prettier": "^4.0.0",
|
"eslint-plugin-storybook": "^0.6.14",
|
||||||
"jest": "^27.3.1",
|
"husky": "^4.3.8",
|
||||||
|
"lint-staged": "^10.5.4",
|
||||||
"prettier": "^2.4.1",
|
"prettier": "^2.4.1",
|
||||||
"rimraf": "^3.0.2",
|
"rollup": "^2.79.1",
|
||||||
"typescript": "^4.4.4",
|
"rollup-plugin-copy": "^3.5.0",
|
||||||
"vite": "^2.6.14",
|
"rollup-plugin-minify-html-literals": "^1.2.6",
|
||||||
"vite-plugin-compression": "^0.3.5",
|
"rollup-plugin-terser": "^7.0.2",
|
||||||
"vite-plugin-ejs": "^1.4.3",
|
"tslib": "^2.3.1",
|
||||||
"vite-plugin-eslint": "^1.3.0"
|
"typescript": "^4.5.2"
|
||||||
|
},
|
||||||
|
"customElements": "custom-elements.json",
|
||||||
|
"eslintConfig": {
|
||||||
|
"parser": "@typescript-eslint/parser",
|
||||||
|
"extends": [
|
||||||
|
"@open-wc",
|
||||||
|
"prettier"
|
||||||
|
],
|
||||||
|
"plugins": [
|
||||||
|
"@typescript-eslint"
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"no-unused-vars": "off",
|
||||||
|
"@typescript-eslint/no-unused-vars": [
|
||||||
|
"error"
|
||||||
|
],
|
||||||
|
"import/no-unresolved": "off",
|
||||||
|
"import/extensions": [
|
||||||
|
"error",
|
||||||
|
"always",
|
||||||
|
{
|
||||||
|
"ignorePackages": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"prettier": {
|
||||||
|
"singleQuote": true,
|
||||||
|
"arrowParens": "avoid"
|
||||||
|
},
|
||||||
|
"husky": {
|
||||||
|
"hooks": {
|
||||||
|
"pre-commit": "lint-staged"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lint-staged": {
|
||||||
|
"*.ts": [
|
||||||
|
"eslint --fix",
|
||||||
|
"prettier --write"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
import resolve from "@rollup/plugin-node-resolve";
|
||||||
|
import { terser } from "rollup-plugin-terser";
|
||||||
|
import minifyHTML from "rollup-plugin-minify-html-literals";
|
||||||
|
import copy from "rollup-plugin-copy";
|
||||||
|
|
||||||
|
// Static assets will vary depending on the application
|
||||||
|
const copyConfig = {
|
||||||
|
targets: [
|
||||||
|
{ src: "node_modules/@webcomponents", dest: "build-modern/node_modules" },
|
||||||
|
{ src: "images", dest: "build-modern" },
|
||||||
|
{ src: "data", dest: "build-modern" },
|
||||||
|
{ src: "index.html", dest: "build-modern" },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
// The main JavaScript bundle for modern browsers that support
|
||||||
|
// JavaScript modules and other ES2015+ features.
|
||||||
|
const config = {
|
||||||
|
input: "dist/src/pendor-clock.js",
|
||||||
|
output: {
|
||||||
|
dir: "build-modern/",
|
||||||
|
format: "es",
|
||||||
|
},
|
||||||
|
plugins: [minifyHTML(), copy(copyConfig), resolve()],
|
||||||
|
preserveEntrySignatures: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (process.env.NODE_ENV !== "development") {
|
||||||
|
config.plugins.push(terser());
|
||||||
|
}
|
||||||
|
|
||||||
|
export default config;
|
|
@ -0,0 +1,157 @@
|
||||||
|
import { LitElement, ReactiveController, ReactiveControllerHost, css, html, render } from "lit";
|
||||||
|
|
||||||
|
const terranMonthIntervals = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
|
||||||
|
|
||||||
|
const pendorMonthIntervals = [0, 1, 25, 49, 73, 97, 121, 145, 146, 147, 171, 195, 211, 243, 267, 291, 292];
|
||||||
|
|
||||||
|
const pendorMonthNames = [
|
||||||
|
"Yestar",
|
||||||
|
"Narrin",
|
||||||
|
"Nenim",
|
||||||
|
"Sulim",
|
||||||
|
"Virta",
|
||||||
|
"Lothess",
|
||||||
|
"Narnya",
|
||||||
|
"Attendes",
|
||||||
|
"Loende",
|
||||||
|
"Cerim",
|
||||||
|
"Urim",
|
||||||
|
"Yavar",
|
||||||
|
"Narquel",
|
||||||
|
"Hiss",
|
||||||
|
"Ring",
|
||||||
|
"Mettare",
|
||||||
|
];
|
||||||
|
|
||||||
|
const pendorWeekdayNames = ["Seren", "Anar", "Noren", "Aldea", "Erwer", "Elenya"];
|
||||||
|
|
||||||
|
const prefix = (n: number) => `${n < 10 ? "0" : ""}${n.toFixed(0)}`;
|
||||||
|
|
||||||
|
export class ClockController implements ReactiveController {
|
||||||
|
host: ReactiveControllerHost;
|
||||||
|
|
||||||
|
value = new Date();
|
||||||
|
timeout: number;
|
||||||
|
// Node and the DOM do not agree on the type. Grrr.
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
private _timerID?: any;
|
||||||
|
|
||||||
|
constructor(host: ReactiveControllerHost, timeout = 1000) {
|
||||||
|
(this.host = host).addController(this);
|
||||||
|
this.timeout = timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
hostConnected() {
|
||||||
|
this._timerID = setInterval(() => {
|
||||||
|
this.value = new Date();
|
||||||
|
this.host.requestUpdate();
|
||||||
|
}, this.timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
hostDisconnected() {
|
||||||
|
clearInterval(this._timerID);
|
||||||
|
this._timerID = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = css`
|
||||||
|
*,
|
||||||
|
*::before,
|
||||||
|
*::after {
|
||||||
|
all: unset;
|
||||||
|
display: revert;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host {
|
||||||
|
padding-top: 0;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
--default-font-size: calc(clamp(0.63rem, calc(0.5rem + 0.63vw), 0.9rem));
|
||||||
|
font-family: Bitwise, Audiowide, Tahoma, Arial, Helvetica, sans-serif;
|
||||||
|
flex: 0 1 auto;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#clock {
|
||||||
|
padding: 0.175rem 0.375rem 0.175rem 0.375rem;
|
||||||
|
background-color: var(--pendorclock-background-color, #000030);
|
||||||
|
color: var(--pendorclock-color, #ffffff);
|
||||||
|
font-size: var(--pendorclock-font-size, --default-font-size);
|
||||||
|
line-height: var(--pendorclock-line-height, 1.35);
|
||||||
|
font-weight: var(--pendorclock-font-weight, 700);
|
||||||
|
min-width: 20ch;
|
||||||
|
max-width: 35ch;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const fontStyle = css`
|
||||||
|
@font-face {
|
||||||
|
font-family: "Audiowide";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: swap;
|
||||||
|
src: url(https://fonts.gstatic.com/s/audiowide/v20/l7gdbjpo0cum0ckerWCdlg_O.woff2) format("woff2");
|
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
|
||||||
|
U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export class PendorClock extends LitElement {
|
||||||
|
static get styles() {
|
||||||
|
return styles;
|
||||||
|
}
|
||||||
|
|
||||||
|
clock: ClockController;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.clock = new ClockController(this, 250);
|
||||||
|
}
|
||||||
|
|
||||||
|
connectedCallback() {
|
||||||
|
super.connectedCallback();
|
||||||
|
if (document.getElementById("pendor-font-block")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const head = document.head || document.getElementsByTagName("head")[0];
|
||||||
|
const style = html`<style id="pendor-font-block" type="text/css">
|
||||||
|
${fontStyle}
|
||||||
|
</style>`;
|
||||||
|
render(style, head);
|
||||||
|
}
|
||||||
|
|
||||||
|
tick(now: Date) {
|
||||||
|
let hours = terranMonthIntervals[now.getMonth()] + now.getDate();
|
||||||
|
if (now.getMonth() > 2 && now.getFullYear() % 4 == 0) {
|
||||||
|
hours++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DST Calculation, and wildly wrong, but WTF
|
||||||
|
hours = hours * 24 + now.getHours() - 16;
|
||||||
|
const year = now.getFullYear() + 16;
|
||||||
|
|
||||||
|
const dayOfYear = hours / 30;
|
||||||
|
hours = hours % 30;
|
||||||
|
|
||||||
|
let seconds = (now.getSeconds() + now.getMinutes() * 60) / 2.25;
|
||||||
|
const minutes = seconds / 40;
|
||||||
|
seconds = seconds % 40;
|
||||||
|
|
||||||
|
const timePart = `${hours.toFixed(0)}:${prefix(minutes)}:${prefix(seconds)}`;
|
||||||
|
const nextMonth = pendorMonthIntervals.findIndex(i => i >= dayOfYear);
|
||||||
|
if (nextMonth === undefined || pendorMonthIntervals[nextMonth - 1] === undefined) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const dayOfMonth = dayOfYear - pendorMonthIntervals[nextMonth - 1];
|
||||||
|
const dayOfWeek = (Math.ceil(dayOfMonth) - 1) % 6;
|
||||||
|
return `${pendorWeekdayNames[dayOfWeek]}, ${pendorMonthNames[nextMonth - 1]} ${dayOfMonth.toFixed(
|
||||||
|
0
|
||||||
|
)}, 00${year.toFixed(0)}, ${timePart}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return html`<div id="clock">${this.tick(this.clock.value)}</div>`;
|
||||||
|
}
|
||||||
|
}
|
61
src/index.ts
61
src/index.ts
|
@ -1,60 +1 @@
|
||||||
const aiMonths = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
|
export { PendorClock } from "./PendorClock.js";
|
||||||
const aiPendor = [0, 1, 25, 49, 73, 97, 121, 145, 146, 147, 171, 195, 211, 243, 267, 291, 292];
|
|
||||||
const asWNames = ["Seren", "Anar", "Noren", "Aldea", "Erwer", "Elenya"];
|
|
||||||
const asMNames = [
|
|
||||||
"Yestar",
|
|
||||||
"Narrin",
|
|
||||||
"Nenim",
|
|
||||||
"Sulim",
|
|
||||||
"Virta",
|
|
||||||
"Lothess",
|
|
||||||
"Narnya",
|
|
||||||
"Attendes",
|
|
||||||
"Loende",
|
|
||||||
"Cerim",
|
|
||||||
"Urim",
|
|
||||||
"Yavar",
|
|
||||||
"Narquel",
|
|
||||||
"Hiss",
|
|
||||||
"Ring",
|
|
||||||
"Mettare",
|
|
||||||
];
|
|
||||||
|
|
||||||
const p = (n: number): string => {
|
|
||||||
const t = n.toFixed(0);
|
|
||||||
return n < 10 ? `0${t}` : `${t}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
const pendorClock = () => {
|
|
||||||
const theDiv: HTMLSpanElement = document.getElementById("pendordate")!;
|
|
||||||
let timer = 0;
|
|
||||||
|
|
||||||
const update = () => {
|
|
||||||
const now = new Date();
|
|
||||||
const days =
|
|
||||||
aiMonths[now.getMonth()]! +
|
|
||||||
now.getDate() +
|
|
||||||
(now.getMonth() > 2 && now.getUTCFullYear() % 4 === 0 ? 1 : 0);
|
|
||||||
const tHours = days * 24 + now.getHours() - 16;
|
|
||||||
const tSeconds = (now.getSeconds() + now.getMinutes() * 60) / 2.25;
|
|
||||||
const [doy, hours, year, minutes, seconds] = [
|
|
||||||
tHours / 30,
|
|
||||||
tHours % 30,
|
|
||||||
now.getUTCFullYear() - 1884,
|
|
||||||
tSeconds / 40,
|
|
||||||
tSeconds % 40,
|
|
||||||
];
|
|
||||||
const mIndex = aiPendor.findIndex((k) => k > doy);
|
|
||||||
const dayOfMonth = doy - aiPendor[mIndex - 1]!;
|
|
||||||
const dayOfWeek = (Math.ceil(dayOfMonth) - 1) % 6;
|
|
||||||
theDiv.innerHTML = `${asWNames[dayOfWeek]!}, ${asMNames[mIndex - 1]!} ${dayOfMonth.toFixed(
|
|
||||||
0
|
|
||||||
)}, 00${year.toFixed(0)}, ${p(hours)}:${p(minutes)}:${p(seconds)}`;
|
|
||||||
window.clearTimeout(timer);
|
|
||||||
timer = window.setTimeout(update, 1250);
|
|
||||||
};
|
|
||||||
|
|
||||||
timer = window.setTimeout(update, 125);
|
|
||||||
};
|
|
||||||
|
|
||||||
window.addEventListener("load", pendorClock);
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { PendorClock } from "./PendorClock.js";
|
||||||
|
|
||||||
|
if (!window.customElements.get("pendor-clock")) {
|
||||||
|
window.customElements.define("pendor-clock", PendorClock);
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
import { TemplateResult, html } from "lit";
|
||||||
|
|
||||||
|
import "../src/pendor-clock.js";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: "PendorClock",
|
||||||
|
component: "pendor-clock",
|
||||||
|
argTypes: {
|
||||||
|
title: { control: "text" },
|
||||||
|
counter: { control: "number" },
|
||||||
|
textColor: { control: "color" },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
interface Story<T> {
|
||||||
|
(args: T): TemplateResult;
|
||||||
|
args?: Partial<T>;
|
||||||
|
argTypes?: Record<string, unknown>;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ArgTypes {
|
||||||
|
title?: string;
|
||||||
|
counter?: number;
|
||||||
|
textColor?: string;
|
||||||
|
slot?: TemplateResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Template: Story<ArgTypes> = ({
|
||||||
|
title = "Hello world",
|
||||||
|
counter = 5,
|
||||||
|
textColor,
|
||||||
|
slot,
|
||||||
|
}: ArgTypes) => html`
|
||||||
|
<pendor-clock
|
||||||
|
style="--pendor-clock-text-color: ${textColor || "black"}"
|
||||||
|
.title=${title}
|
||||||
|
.counter=${counter}
|
||||||
|
>
|
||||||
|
${slot}
|
||||||
|
</pendor-clock>
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const Regular = Template.bind({});
|
||||||
|
|
||||||
|
export const CustomTitle = Template.bind({});
|
||||||
|
CustomTitle.args = {
|
||||||
|
title: "My title",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const CustomCounter = Template.bind({});
|
||||||
|
CustomCounter.args = {
|
||||||
|
counter: 123456,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SlottedContent = Template.bind({});
|
||||||
|
SlottedContent.args = {
|
||||||
|
slot: html`<p>Slotted content</p>`,
|
||||||
|
};
|
||||||
|
SlottedContent.argTypes = {
|
||||||
|
slot: { table: { disable: true } },
|
||||||
|
};
|
|
@ -1,30 +1,21 @@
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"sourceMap": false,
|
"target": "es2018",
|
||||||
"noImplicitAny": false,
|
"module": "esnext",
|
||||||
"module": "esnext",
|
"moduleResolution": "node",
|
||||||
"target": "es6",
|
"noEmitOnError": true,
|
||||||
"lib": ["es6", "dom", "dom.iterable"],
|
"lib": ["es2017", "dom"],
|
||||||
"removeComments": true,
|
"strict": true,
|
||||||
"allowSyntheticDefaultImports": true,
|
"esModuleInterop": false,
|
||||||
"declaration": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
"allowJs": true,
|
"experimentalDecorators": true,
|
||||||
"strict": true,
|
"importHelpers": true,
|
||||||
"baseUrl": "./",
|
"outDir": "dist",
|
||||||
"esModuleInterop": true,
|
"sourceMap": true,
|
||||||
"resolveJsonModule": true,
|
"inlineSources": true,
|
||||||
"moduleResolution": "node",
|
"rootDir": "./",
|
||||||
"downlevelIteration": true,
|
"declaration": true,
|
||||||
"noUnusedLocals": true /* Report errors on unused locals. */,
|
"incremental": true
|
||||||
"experimentalDecorators": true,
|
},
|
||||||
"noUnusedParameters": true /* Report errors on unused parameters. */,
|
"include": ["**/*.ts"]
|
||||||
"noImplicitReturns": true /* Report error when not all code paths in function return a value. */,
|
|
||||||
"noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */,
|
|
||||||
"noUncheckedIndexedAccess": true /* Include 'undefined' in index signature results */,
|
|
||||||
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */,
|
|
||||||
"paths": {
|
|
||||||
"@/*": ["./src/*"]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"include": ["./src/**/*"]
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
import path from "path";
|
|
||||||
import viteCompression from "vite-plugin-compression";
|
|
||||||
import eslintPlugin from "vite-plugin-eslint";
|
|
||||||
|
|
||||||
const config = (mode) => ({
|
|
||||||
plugins: [
|
|
||||||
viteCompression({ filter: /\.(js|css|map)$/, algorithm: "gzip", ext: ".gz" }),
|
|
||||||
viteCompression({ filter: /\.(js|css|map)$/, algorithm: "brotliCompress", ext: ".br" }),
|
|
||||||
eslintPlugin({ cache: true }),
|
|
||||||
],
|
|
||||||
|
|
||||||
sourcemap: mode === "development",
|
|
||||||
|
|
||||||
build: {
|
|
||||||
outDir: "build",
|
|
||||||
sourcemap: mode === "development",
|
|
||||||
minify: !mode === "development",
|
|
||||||
brotliSize: false,
|
|
||||||
emptyOutDir: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
optimizeDeps: {
|
|
||||||
allowNodeBuiltins: false,
|
|
||||||
},
|
|
||||||
|
|
||||||
server: {
|
|
||||||
proxy: {
|
|
||||||
// Allows us to run the proxy server independent of the content, and still
|
|
||||||
// get full-service.
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export default config;
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
// import { hmrPlugin, presets } from '@open-wc/dev-server-hmr';
|
||||||
|
|
||||||
|
/** Use Hot Module replacement by adding --hmr to the start command */
|
||||||
|
const hmr = process.argv.includes('--hmr');
|
||||||
|
|
||||||
|
export default /** @type {import('@web/dev-server').DevServerConfig} */ ({
|
||||||
|
open: '/demo/',
|
||||||
|
/** Use regular watch mode if HMR is not enabled. */
|
||||||
|
watch: !hmr,
|
||||||
|
/** Resolve bare module imports */
|
||||||
|
nodeResolve: {
|
||||||
|
exportConditions: ['browser', 'development'],
|
||||||
|
},
|
||||||
|
|
||||||
|
/** Compile JS for older browsers. Requires @web/dev-server-esbuild plugin */
|
||||||
|
// esbuildTarget: 'auto'
|
||||||
|
|
||||||
|
/** Set appIndex to enable SPA routing */
|
||||||
|
// appIndex: 'demo/index.html',
|
||||||
|
|
||||||
|
plugins: [
|
||||||
|
/** Use Hot Module Replacement by uncommenting. Requires @open-wc/dev-server-hmr plugin */
|
||||||
|
// hmr && hmrPlugin({ exclude: ['**/*/node_modules/**/*'], presets: [presets.litElement] }),
|
||||||
|
],
|
||||||
|
|
||||||
|
// See documentation for all available options
|
||||||
|
});
|
Loading…
Reference in New Issue