From d14fb49067a6a1625a004becddfe80434dd3dee0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 15 Dec 2023 05:11:34 +0000 Subject: [PATCH 01/16] Add renovate.json --- renovate.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 renovate.json diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..5db72dd --- /dev/null +++ b/renovate.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:recommended" + ] +} From 1288beff2d1fd12e636ea5c90bce0d7ca22334c3 Mon Sep 17 00:00:00 2001 From: georgei Date: Fri, 23 Feb 2024 15:15:46 +0100 Subject: [PATCH 02/16] Add renovate config --- renovate.json | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/renovate.json b/renovate.json index 5db72dd..9f35552 100644 --- a/renovate.json +++ b/renovate.json @@ -1,6 +1,11 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "config:recommended" - ] + "extends": ["config:base"], + "internalChecksFilter": "strict", + "updateNotScheduled": false, + "prCreation": "approval", + "minimumReleaseAge": "21 days", + "pre-commit": { + "enabled": true + } } From 93d4a02957c49b88472fe7e52ead7b63ed994b1d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 14:19:06 +0000 Subject: [PATCH 03/16] Update actions/checkout action to v4 --- .github/workflows/npm-publish.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index f24a210..487e98a 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -11,7 +11,7 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-node@v3 with: node-version: 16 @@ -21,7 +21,7 @@ jobs: needs: build runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-node@v3 with: node-version: 16 From 65c4ba06306fe0b1dedab4a8ae11e769305727c9 Mon Sep 17 00:00:00 2001 From: georgei Date: Fri, 23 Feb 2024 15:34:27 +0100 Subject: [PATCH 04/16] Change tab width to 2 and format project files --- .eslintrc.js | 255 +++++++++--------- .stylelintrc.js | 43 +-- README.md | 64 +++-- playground/example.json | 25 +- playground/index.html | 12 +- prettier.config.js | 12 +- src/DocumentViewer.scss | 2 +- src/DocumentViewer.tsx | 28 +- .../Accordion/Accordion.mixins.scss | 149 +++++----- src/components/Accordion/Accordion.scss | 4 +- src/components/Accordion/Accordion.tsx | 26 +- src/components/Accordion/types.ts | 22 +- .../AccordionItem/AccordionItem.scss | 15 +- .../AccordionItem/AccordionItem.tsx | 88 +++--- src/components/AccordionItem/types.ts | 6 +- .../AccordionItem/useAccordionContext.ts | 2 +- src/components/Chapter/Chapter.tsx | 16 +- .../CollapsibleContainer.scss | 7 +- .../CollapsibleContainer.tsx | 30 ++- src/components/CollapsibleContainer/types.ts | 4 +- .../ContentElements/ContentElements.tsx | 154 +++++------ src/components/Heading/Heading.mixins.scss | 20 +- src/components/Heading/Heading.scss | 4 +- src/components/Heading/Heading.tsx | 16 +- src/components/Icon/Icon.scss | 24 +- src/components/Icon/Icon.tsx | 50 ++-- .../InternalReference/InternalReference.tsx | 19 +- src/components/Link/Link.mixins.scss | 94 +++---- src/components/Link/Link.scss | 2 +- src/components/Link/Link.tsx | 33 ++- src/components/Link/types.ts | 10 +- src/components/LinkButton/LinkButton.tsx | 10 +- src/components/List/List.mixins.scss | 32 +-- src/components/List/List.scss | 12 +- src/components/List/List.tsx | 10 +- src/components/List/ListItem.tsx | 4 +- src/components/List/types.ts | 16 +- src/components/ListElemennt/List.tsx | 20 +- src/components/Paragraph/Paragraph.scss | 12 +- src/components/Paragraph/Paragraph.tsx | 16 +- src/components/Section/Section.scss | 8 +- src/components/Section/Section.tsx | 28 +- src/components/Table/Table.mixins.scss | 74 ++--- src/components/Table/Table.scss | 14 +- src/components/Table/Table.tsx | 52 ++-- src/components/Text/Text.tsx | 10 +- src/components/Weblink/Weblink.tsx | 4 +- src/index.tsx | 48 ++-- src/style/mixins.scss | 31 +-- src/style/utilities/alignment.scss | 2 +- src/style/utilities/spacing.scss | 10 +- src/style/utilities/typography.scss | 6 +- src/style/variables.scss | 248 ++++++++--------- src/types/index.ts | 34 ++- src/utils/id-generator.ts | 4 +- src/utils/scroll.ts | 18 +- tsconfig.json | 36 +-- webpack.common.js | 72 ++--- webpack.dev.js | 32 +-- webpack.prod.js | 46 ++-- 60 files changed, 1108 insertions(+), 1037 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 38cfc57..c60849a 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,138 +1,141 @@ module.exports = { - parser: '@typescript-eslint/parser', - plugins: ['react', '@typescript-eslint', 'import', 'eslint-plugin-tsdoc', 'jsx-a11y'], - extends: [ - 'eslint:recommended', - 'plugin:react/recommended', - 'plugin:@typescript-eslint/eslint-recommended', - 'plugin:@typescript-eslint/recommended' /*'prettier/@typescript-eslint'*/ - ], - parserOptions: { - ecmaVersion: 2020, - sourceType: 'module', - ecmaFeatures: { - modules: true, - jsx: true - } + parser: '@typescript-eslint/parser', + plugins: ['react', '@typescript-eslint', 'import', 'eslint-plugin-tsdoc', 'jsx-a11y'], + extends: [ + 'eslint:recommended', + 'plugin:react/recommended', + 'plugin:@typescript-eslint/eslint-recommended', + 'plugin:@typescript-eslint/recommended' /*'prettier/@typescript-eslint'*/, + ], + parserOptions: { + ecmaVersion: 2020, + sourceType: 'module', + ecmaFeatures: { + modules: true, + jsx: true, }, - env: { - browser: true, - node: true, - es2020: true + }, + env: { + browser: true, + node: true, + es2020: true, + }, + settings: { + react: { + pragma: 'h', + version: '16.0', }, - settings: { - react: { - pragma: 'h', - version: '16.0' - }, - 'import/resolver': { - node: { - extensions: ['.js', '.jsx', '.ts', '.tsx'] - }, - typescript: { - project: './tsconfig.json' - } - } + 'import/resolver': { + node: { + extensions: ['.js', '.jsx', '.ts', '.tsx'], + }, + typescript: { + project: './tsconfig.json', + }, }, - rules: { - 'no-console': 0, - 'class-methods-use-this': 'off', - 'no-underscore-dangle': 'off', - 'import/prefer-default-export': 'off', - 'no-debugger': 'warn', - indent: 'off', - 'import/extensions': [ - 'error', - 'ignorePackages', - { - js: 'never', - jsx: 'never', - ts: 'never', - tsx: 'never' - } - ], - // Disabled: doesn't play well with workspaces, more investigation needed - // 'import/no-extraneous-dependencies': ['error', { devDependencies: true }], - 'max-len': [ - 'error', - { - code: 150, - tabWidth: 2, - ignoreComments: true, // Allow long comments in the code - ignoreUrls: true, - ignoreStrings: true, - ignoreTemplateLiterals: true - } - ], - 'prefer-destructuring': 'off', - 'arrow-parens': [0, 'as-needed'], - // Do not care about dangling comma presence - 'comma-dangle': 'off', - // // Do not care about operators linebreak - 'operator-linebreak': 'off', - // // Do not care about arrow function linebreak - 'implicit-arrow-linebreak': 'off', - // // Do not care about empty lines about props - 'lines-between-class-members': 'off', - // This is not important rule - 'object-curly-newline': 'off', - // // Styling rule which doesn't add anything - 'no-multiple-empty-lines': 'off', - // This rule doesn't make sense in the latest browsers - radix: 'off', - // This serves no practical purpose - 'eol-last': 'off', + }, + rules: { + 'no-console': 0, + 'class-methods-use-this': 'off', + 'no-underscore-dangle': 'off', + 'import/prefer-default-export': 'off', + 'no-debugger': 'warn', + indent: 'off', + 'import/extensions': [ + 'error', + 'ignorePackages', + { + js: 'never', + jsx: 'never', + ts: 'never', + tsx: 'never', + }, + ], + // Disabled: doesn't play well with workspaces, more investigation needed + // 'import/no-extraneous-dependencies': ['error', { devDependencies: true }], + 'max-len': [ + 'error', + { + code: 150, + tabWidth: 2, + ignoreComments: true, // Allow long comments in the code + ignoreUrls: true, + ignoreStrings: true, + ignoreTemplateLiterals: true, + }, + ], + 'prefer-destructuring': 'off', + 'arrow-parens': [0, 'as-needed'], + // Do not care about dangling comma presence + 'comma-dangle': 'off', + // // Do not care about operators linebreak + 'operator-linebreak': 'off', + // // Do not care about arrow function linebreak + 'implicit-arrow-linebreak': 'off', + // // Do not care about empty lines about props + 'lines-between-class-members': 'off', + // This is not important rule + 'object-curly-newline': 'off', + // // Styling rule which doesn't add anything + 'no-multiple-empty-lines': 'off', + // This rule doesn't make sense in the latest browsers + radix: 'off', + // This serves no practical purpose + 'eol-last': 'off', - // the base rule can report incorrect errors - 'no-useless-constructor': 'off', + // the base rule can report incorrect errors + 'no-useless-constructor': 'off', - // Typescript Rules - '@typescript-eslint/no-unused-vars': ['error', { ignoreRestSiblings: true, vars: 'local' }], - '@typescript-eslint/explicit-member-accessibility': 'off', - '@typescript-eslint/no-explicit-any': 'off', - '@typescript-eslint/explicit-function-return-type': 'off', - '@typescript-eslint/indent': 'off', - '@typescript-eslint/no-empty-function': ['error', { allow: ['arrowFunctions'] }], - '@typescript-eslint/ban-types': 'off', - '@typescript-eslint/ban-ts-comment': 'off', - '@typescript-eslint/explicit-module-boundary-types': 'off', + // Typescript Rules + '@typescript-eslint/no-unused-vars': ['error', { ignoreRestSiblings: true, vars: 'local' }], + '@typescript-eslint/explicit-member-accessibility': 'off', + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/indent': 'off', + '@typescript-eslint/no-empty-function': ['error', { allow: ['arrowFunctions'] }], + '@typescript-eslint/ban-types': 'off', + '@typescript-eslint/ban-ts-comment': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', - // React Rules - 'react/prop-types': 'off', - 'react/display-name': 'off', + // React Rules + 'react/prop-types': 'off', + 'react/display-name': 'off', - // TSDoc - 'tsdoc/syntax': 'warn', + // TSDoc + 'tsdoc/syntax': 'warn', - // a11y - 'jsx-a11y/alt-text': 'error', - 'jsx-a11y/aria-role': 'error', - 'jsx-a11y/aria-props': 'error', - 'jsx-a11y/aria-unsupported-elements': 'error', - 'jsx-a11y/role-has-required-aria-props': 'error', - 'jsx-a11y/role-supports-aria-props': 'error', - 'jsx-a11y/tabindex-no-positive': 'error', - 'jsx-a11y/no-redundant-roles': 'error', - 'jsx-a11y/anchor-has-content': 'error', - 'jsx-a11y/anchor-is-valid': 'error', - 'jsx-a11y/img-redundant-alt': 'error', - 'jsx-a11y/interactive-supports-focus': 'error', - 'jsx-a11y/autocomplete-valid': 'error', - 'jsx-a11y/no-static-element-interactions': 'error', - 'jsx-a11y/no-noninteractive-tabindex': 'error', - 'jsx-a11y/mouse-events-have-key-events': 'error', + // a11y + 'jsx-a11y/alt-text': 'error', + 'jsx-a11y/aria-role': 'error', + 'jsx-a11y/aria-props': 'error', + 'jsx-a11y/aria-unsupported-elements': 'error', + 'jsx-a11y/role-has-required-aria-props': 'error', + 'jsx-a11y/role-supports-aria-props': 'error', + 'jsx-a11y/tabindex-no-positive': 'error', + 'jsx-a11y/no-redundant-roles': 'error', + 'jsx-a11y/anchor-has-content': 'error', + 'jsx-a11y/anchor-is-valid': 'error', + 'jsx-a11y/img-redundant-alt': 'error', + 'jsx-a11y/interactive-supports-focus': 'error', + 'jsx-a11y/autocomplete-valid': 'error', + 'jsx-a11y/no-static-element-interactions': 'error', + 'jsx-a11y/no-noninteractive-tabindex': 'error', + 'jsx-a11y/mouse-events-have-key-events': 'error', - // Debugging import rules. - // These can be computationally expensive, enable them sparingly. - 'import/no-cycle': 'error' + // Debugging import rules. + // These can be computationally expensive, enable them sparingly. + 'import/no-cycle': 'error', + }, + overrides: [ + { + // enable the rule specifically for TypeScript files + files: ['*.ts', '*.tsx'], + rules: { + '@typescript-eslint/explicit-member-accessibility': [ + 'error', + { accessibility: 'off', overrides: { properties: 'explicit' } }, + ], + }, }, - overrides: [ - { - // enable the rule specifically for TypeScript files - files: ['*.ts', '*.tsx'], - rules: { - '@typescript-eslint/explicit-member-accessibility': ['error', { accessibility: 'off', overrides: { properties: 'explicit' } }] - } - } - ] + ], }; diff --git a/.stylelintrc.js b/.stylelintrc.js index d1b8454..42dc04a 100644 --- a/.stylelintrc.js +++ b/.stylelintrc.js @@ -1,28 +1,29 @@ -const bemPattern = '^.[adv|adyen]*(?:-[a-zA-Z0-9]+)*(?:__[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*)?(?:--[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*)?(?:\\[.+\\])?$'; +const bemPattern = + '^.[adv|adyen]*(?:-[a-zA-Z0-9]+)*(?:__[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*)?(?:--[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*)?(?:\\[.+\\])?$'; module.exports = { - syntax: 'scss', - extends: ['stylelint-config-recommended', 'stylelint-config-sass-guidelines'], - plugins: ['stylelint-scss'], - rules: { - indentation: [4, { indentClosingBrace: false }], - 'max-empty-lines': 3, - 'max-nesting-depth': 3, - 'no-descending-specificity': null, - 'property-no-vendor-prefix': null, - 'selector-no-vendor-prefix': null, + syntax: 'scss', + extends: ['stylelint-config-recommended', 'stylelint-config-sass-guidelines'], + plugins: ['stylelint-scss'], + rules: { + indentation: [2, { indentClosingBrace: false }], + 'max-empty-lines': 3, + 'max-nesting-depth': 3, + 'no-descending-specificity': null, + 'property-no-vendor-prefix': null, + 'selector-no-vendor-prefix': null, - // Replaced CSS with SCSS rules - 'at-rule-no-unknown': null, + // Replaced CSS with SCSS rules + 'at-rule-no-unknown': null, - // stylelint-scss plugin - 'scss/at-rule-no-unknown': true, + // stylelint-scss plugin + 'scss/at-rule-no-unknown': true, - // BEM naming - 'selector-class-pattern': [bemPattern, { resolveNestedSelectors: true }], - 'scss/at-mixin-pattern': bemPattern, - 'scss/dollar-variable-pattern': bemPattern, + // BEM naming + 'selector-class-pattern': [bemPattern, { resolveNestedSelectors: true }], + 'scss/at-mixin-pattern': bemPattern, + 'scss/dollar-variable-pattern': bemPattern, - 'scss/at-import-partial-extension-blacklist': null - } + 'scss/at-import-partial-extension-blacklist': null, + }, }; diff --git a/README.md b/README.md index 573c9eb..8bbcff6 100644 --- a/README.md +++ b/README.md @@ -8,16 +8,16 @@ Adyen Document Viewer provides you with a flexible way of rendering Adyen-genera 1. Install the package using [npm](https://www.npmjs.com/) or [yarn](https://yarnpkg.com/) - ```sh - npm install @adyen/adyen-document-viewer --save - ``` + ```sh + npm install @adyen/adyen-document-viewer --save + ``` 2. Import [Adyen Document Viewer Node package](https://www.npmjs.com/package/@adyen/adyen-document-viewer) into your application - ```js - import AdyenDocumentViewer from '@adyen/adyen-document-viewer'; - import '@adyen/adyen-document-viewer/dist/adyen-document-viewer.min.css'; - ``` + ```js + import AdyenDocumentViewer from '@adyen/adyen-document-viewer'; + import '@adyen/adyen-document-viewer/dist/adyen-document-viewer.min.css'; + ``` ### CDN @@ -25,7 +25,10 @@ Include the script and stylesheet to a `.html` file ```html - + ``` **NOTE:** By choosing this method, `AdyenDocumentViewer` class will become available globally in your application. @@ -34,31 +37,31 @@ Include the script and stylesheet to a `.html` file 1. The component requires an HTML element to render its contents. Create an instance of `AdyenDocumentViewer` and pass the HTML element itself or a `querySelector` string value which targets it - ```js - const documentViewer = new AdyenDocumentViewer('#test'); - ``` + ```js + const documentViewer = new AdyenDocumentViewer('#test'); + ``` 2. Call the `render` method, and pass the document as parameter - ```js - documentViewer.render(document); - ``` + ```js + documentViewer.render(document); + ``` -## Styling +## Styling Adyen Document Viewer is themeable and uses CSS variables that can be overridden in order to achieve the desired style. Overrides should be added for `.adyen-document-viewer` class. ### Overriding styles example -1. Create `override.css` with the variables that you would like to style +1. Create `override.css` with the variables that you would like to style ```css .adyen-document-viewer { - --adv-background-color: #ff8888; - --adv-heading-font-size: 48px; + --adv-background-color: #ff8888; + --adv-heading-font-size: 48px; } ``` - + 2. Make sure to import the `override.css` after importing library's main CSS ```js @@ -67,6 +70,7 @@ Adyen Document Viewer is themeable and uses CSS variables that can be overridden ``` ### Available CSS variables + ```css /* Colors */ --adv-color-white: #fff; /* backgrounds */ @@ -79,7 +83,8 @@ Adyen Document Viewer is themeable and uses CSS variables that can be overridden --adv-background-color: var(--adv-color-white); /* Fonts */ ---adv-text-font-family: -apple-system, blinkmacsystemfont, 'Segoe UI', roboto, oxygen, ubuntu, cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; +--adv-text-font-family: -apple-system, blinkmacsystemfont, 'Segoe UI', roboto, oxygen, ubuntu, + cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; --adv-text-color: var(--adv-color-black); --adv-text-font-weight-regular: 400; --adv-text-font-weight-semi-bold: 600; @@ -134,7 +139,9 @@ Adyen Document Viewer is themeable and uses CSS variables that can be overridden --adv-accordion-toggle-padding: 0; --adv-accordion-toggle-width: var(--adv-spacing-12); --adv-accordion-content-margin: 0 0 var(--adv-spacing-24); ---adv-accordion-content-padding: 0 var(--adv-spacing-16) 0 calc(var(--adv-spacing-32) + var(--adv-spacing-12)); +--adv-accordion-content-padding: 0 var(--adv-spacing-16) 0 calc( + var(--adv-spacing-32) + var(--adv-spacing-12) + ); --adv-accordion-content-closed-margin: 0; --adv-accordion-transition-duration: var(--adv-transition-duration); --adv-accordion-transition-function: var(--adv-transition-function); @@ -196,11 +203,16 @@ Adyen Document Viewer is themeable and uses CSS variables that can be overridden --adv-table-cell-padding-right: calc(var(--adv-spacing-16) + var(--adv-spacing-24)); --adv-table-cell-padding-bottom: var(--adv-spacing-12); --adv-table-cell-padding-left: var(--adv-spacing-16); ---adv-table-cell-padding: var(--adv-table-cell-padding-top) var(--adv-table-cell-padding-right) var(--adv-table-cell-padding-bottom) var(--adv-table-cell-padding-left); +--adv-table-cell-padding: var(--adv-table-cell-padding-top) var(--adv-table-cell-padding-right) var( + --adv-table-cell-padding-bottom + ) var(--adv-table-cell-padding-left); --adv-table-cell-text-align: left; --adv-table-first-column-padding-left: var(--adv-spacing-24); --adv-table-condensed-cell-padding-y: var(--adv-spacing-8); ---adv-table-condensed-cell-padding: var(--adv-table-condensed-cell-padding-y) var(--adv-table-cell-padding-right) var(--adv-table-condensed-cell-padding-y) var(--adv-table-cell-padding-left); +--adv-table-condensed-cell-padding: var(--adv-table-condensed-cell-padding-y) var( + --adv-table-cell-padding-right + ) + var(--adv-table-condensed-cell-padding-y) var(--adv-table-cell-padding-left); --adv-table-condensed-font-size: var(--adv-text-font-size-small); ``` @@ -210,12 +222,13 @@ To run the development environment: 1. Clone [this repository](https://github.com/Adyen/adyen-document-viewer). 2. Install the dependencies by running: - + ```sh npm install ``` + 3. Run the development environment, which starts a server listening on [http://localhost:8080](http://localhost:8080): - + ```sh npm start ``` @@ -225,6 +238,7 @@ To run the development environment: If you have a feature request, or spotted a bug or a technical problem, [contact our support team](https://www.adyen.help/hc/en-us/requests/new). ## Contributing + We strongly encourage you to contribute to our repository. Find out more in our [contribution guidelines](https://github.com/Adyen/.github/blob/master/CONTRIBUTING.md). ## License diff --git a/playground/example.json b/playground/example.json index 59908bc..9bc79e9 100644 --- a/playground/example.json +++ b/playground/example.json @@ -47,10 +47,7 @@ { "type": "text", "content": " This is a bold and italic example.", - "styles": [ - "BOLD", - "ITALIC" - ] + "styles": ["BOLD", "ITALIC"] }, { "type": "paragraph", @@ -73,10 +70,7 @@ { "type": "text", "content": "first item in BI.", - "styles": [ - "BOLD", - "ITALIC" - ] + "styles": ["BOLD", "ITALIC"] } ], "subList": null @@ -200,9 +194,7 @@ { "type": "text", "content": "Row 1", - "styles": [ - "BOLD" - ] + "styles": ["BOLD"] } ] }, @@ -230,9 +222,7 @@ { "type": "text", "content": "Row 2", - "styles": [ - "BOLD" - ] + "styles": ["BOLD"] } ] }, @@ -266,10 +256,7 @@ "styles": [] }, "style": { - "columnSizes": [ - "SMALL", - "LARGE" - ], + "columnSizes": ["SMALL", "LARGE"], "alignment": "LEFT" }, "label": "tableReference" @@ -281,4 +268,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/playground/index.html b/playground/index.html index b24167c..b66f851 100644 --- a/playground/index.html +++ b/playground/index.html @@ -1,10 +1,10 @@ - - + + Adyen Document Viewer Example - - + +
- - \ No newline at end of file + + diff --git a/prettier.config.js b/prettier.config.js index 33bcb4c..e80a806 100644 --- a/prettier.config.js +++ b/prettier.config.js @@ -1,8 +1,8 @@ module.exports = { - arrowParens: 'always', - bracketSpacing: true, - trailingComma: 'none', - tabWidth: 4, - printWidth: 150, - singleQuote: true + arrowParens: 'always', + bracketSpacing: true, + printWidth: 100, + singleQuote: true, + tabWidth: 2, + trailingComma: 'all', }; diff --git a/src/DocumentViewer.scss b/src/DocumentViewer.scss index 69cf651..d0d7af7 100644 --- a/src/DocumentViewer.scss +++ b/src/DocumentViewer.scss @@ -1,5 +1,5 @@ @import 'src/style'; .adyen-document-viewer { - background-color: var(--adv-background-color); + background-color: var(--adv-background-color); } diff --git a/src/DocumentViewer.tsx b/src/DocumentViewer.tsx index 3daa1d5..c5e862d 100644 --- a/src/DocumentViewer.tsx +++ b/src/DocumentViewer.tsx @@ -6,15 +6,23 @@ import Heading from './components/Heading/Heading'; import Text from './components/Text/Text'; import ContentElements from './components/ContentElements/ContentElements'; -export default function DocumentViewer({ document, className, onExpandSection }: DocumentViewerProps) { - const classNames = cx('adyen-document-viewer', className); +export default function DocumentViewer({ + document, + className, + onExpandSection, +}: DocumentViewerProps) { + const classNames = cx('adyen-document-viewer', className); - return ( -
- - - - -
- ); + return ( +
+ + + + +
+ ); } diff --git a/src/components/Accordion/Accordion.mixins.scss b/src/components/Accordion/Accordion.mixins.scss index 844a1de..439edde 100644 --- a/src/components/Accordion/Accordion.mixins.scss +++ b/src/components/Accordion/Accordion.mixins.scss @@ -1,109 +1,112 @@ @import 'src/style/mixins'; @mixin adv-accordion { - @include adv-component-base; + @include adv-component-base; } @mixin adv-accordion--container { - border: var(--adv-accordion-item-border-width) solid var(--adv-accordion-item-border-color); - border-radius: var(--adv-accordion-border-radius); + border: var(--adv-accordion-item-border-width) solid var(--adv-accordion-item-border-color); + border-radius: var(--adv-accordion-border-radius); - .adv-accordion__item { - &:first-child { - border-top-color: transparent; + .adv-accordion__item { + &:first-child { + border-top-color: transparent; - > .adv-accordion__header { - border-radius: var(--adv-accordion-header-border-radius) var(--adv-accordion-header-border-radius) 0 0; - } - } + > .adv-accordion__header { + border-radius: var(--adv-accordion-header-border-radius) + var(--adv-accordion-header-border-radius) 0 0; + } + } - &:last-child { - border-bottom-color: transparent; + &:last-child { + border-bottom-color: transparent; - &:not(.adv-accordion__item--open) > .adv-accordion__header { - border-radius: 0 0 var(--adv-accordion-header-border-radius) var(--adv-accordion-header-border-radius); - } - } + &:not(.adv-accordion__item--open) > .adv-accordion__header { + border-radius: 0 0 var(--adv-accordion-header-border-radius) + var(--adv-accordion-header-border-radius); + } } + } } @mixin adv-accordion__item { - border-bottom: var(--adv-accordion-item-border-width) solid var(--adv-accordion-between-items-border-color); - border-top: var(--adv-accordion-item-border-width) solid var(--adv-accordion-item-border-color); - position: relative; - - &:last-child { - border-bottom-color: var(--adv-accordion-item-border-color); - } + border-bottom: var(--adv-accordion-item-border-width) solid + var(--adv-accordion-between-items-border-color); + border-top: var(--adv-accordion-item-border-width) solid var(--adv-accordion-item-border-color); + position: relative; + + &:last-child { + border-bottom-color: var(--adv-accordion-item-border-color); + } } @mixin adv-accordion__item--open { - overflow: visible; + overflow: visible; } @mixin adv-accordion__header { - color: var(--adv-accordion-header-color); - cursor: pointer; - display: flex; - padding: var(--adv-accordion-header-padding); - transition-duration: var(--adv-accordion-transition-duration); - transition-property: var(--adv-accordion-transition-property); - - &:hover { - background-color: var(--adv-accordion-header-hover-background-color); - } - - &:active { - background-color: var(--adv-accordion-header-active-background-color); - } - - &:focus { - @include adv-focus-ring; - - outline: none; - } + color: var(--adv-accordion-header-color); + cursor: pointer; + display: flex; + padding: var(--adv-accordion-header-padding); + transition-duration: var(--adv-accordion-transition-duration); + transition-property: var(--adv-accordion-transition-property); + + &:hover { + background-color: var(--adv-accordion-header-hover-background-color); + } + + &:active { + background-color: var(--adv-accordion-header-active-background-color); + } + + &:focus { + @include adv-focus-ring; + + outline: none; + } } @mixin adv-accordion__title-wrapper { - flex: 1; + flex: 1; } @mixin adv-accordion__title { - color: var(--adv-accordion-title-color); - font-weight: var(--adv-accordion-header-font-weight); + color: var(--adv-accordion-title-color); + font-weight: var(--adv-accordion-header-font-weight); } @mixin adv-accordion__toggle { - line-height: 1; - margin: var(--adv-accordion-toggle-margin); - padding: var(--adv-accordion-toggle-padding); - width: var(--adv-accordion-toggle-width); + line-height: 1; + margin: var(--adv-accordion-toggle-margin); + padding: var(--adv-accordion-toggle-padding); + width: var(--adv-accordion-toggle-width); } @mixin adv-accordion__content { - box-sizing: border-box; + box-sizing: border-box; + margin: var(--adv-accordion-content-margin); + overflow-x: auto; + overflow-y: hidden; + padding: var(--adv-accordion-content-padding); + transition-duration: var(--adv-accordion-transition-duration); + transition-property: var(--adv-accordion-transition-property); + + .adv-accordion__item > & { + margin: var(--adv-accordion-content-closed-margin); + } + + .adv-accordion__item--open > & { margin: var(--adv-accordion-content-margin); - overflow-x: auto; - overflow-y: hidden; - padding: var(--adv-accordion-content-padding); - transition-duration: var(--adv-accordion-transition-duration); - transition-property: var(--adv-accordion-transition-property); - - .adv-accordion__item > & { - margin: var(--adv-accordion-content-closed-margin); - } + } - .adv-accordion__item--open > & { - margin: var(--adv-accordion-content-margin); - } - - .adv-accordion--max-height-transition .adv-accordion__item > & { - max-height: 0; - transition-duration: var(--adv-accordion-css-animated-transition-duration); - transition-property: var(--adv-accordion-css-animated-transition-property); - } + .adv-accordion--max-height-transition .adv-accordion__item > & { + max-height: 0; + transition-duration: var(--adv-accordion-css-animated-transition-duration); + transition-property: var(--adv-accordion-css-animated-transition-property); + } - .adv-accordion--max-height-transition .adv-accordion__item--open > & { - max-height: var(--adv-accordion-css-animated-max-height); - } + .adv-accordion--max-height-transition .adv-accordion__item--open > & { + max-height: var(--adv-accordion-css-animated-max-height); + } } diff --git a/src/components/Accordion/Accordion.scss b/src/components/Accordion/Accordion.scss index 730c2e1..78599fe 100644 --- a/src/components/Accordion/Accordion.scss +++ b/src/components/Accordion/Accordion.scss @@ -1,9 +1,9 @@ @import 'Accordion.mixins'; .adv-accordion { - @include adv-accordion; + @include adv-accordion; } .adv-accordion--container { - @include adv-accordion--container; + @include adv-accordion--container; } diff --git a/src/components/Accordion/Accordion.tsx b/src/components/Accordion/Accordion.tsx index bf500e9..3e11b28 100644 --- a/src/components/Accordion/Accordion.tsx +++ b/src/components/Accordion/Accordion.tsx @@ -5,16 +5,22 @@ import { AccordionProps, AccordionItemState } from './types'; import { AccordionContext } from './AccordionContext'; import './Accordion.scss'; -export default function Accordion({ children, className, expand = false, type, onExpandSection }: AccordionProps) { - const [items, setItems] = useState([]); +export default function Accordion({ + children, + className, + expand = false, + type, + onExpandSection, +}: AccordionProps) { + const [items, setItems] = useState([]); - const classNames = cx('adv-accordion', className, { - 'adv-accordion--container': type === 'container' - }); + const classNames = cx('adv-accordion', className, { + 'adv-accordion--container': type === 'container', + }); - return ( - -
{children}
-
- ); + return ( + +
{children}
+
+ ); } diff --git a/src/components/Accordion/types.ts b/src/components/Accordion/types.ts index 19f1aa5..bf54447 100644 --- a/src/components/Accordion/types.ts +++ b/src/components/Accordion/types.ts @@ -2,21 +2,21 @@ import { ComponentChildren } from 'preact'; import AccordionItem from '../AccordionItem/AccordionItem'; export interface AccordionProps { - children: ComponentChildren; - className?: string; - expand?: boolean; - type?: string; - onExpandSection?: (title: string) => void; + children: ComponentChildren; + className?: string; + expand?: boolean; + type?: string; + onExpandSection?: (title: string) => void; } export type AccordionItemState = { - id: string; - isOpen: boolean; + id: string; + isOpen: boolean; }; export type AccordionContextType = { - expand: boolean; - items: AccordionItemState[]; - setItems: (items: AccordionItemState[] | ((items) => AccordionItemState[])) => void; - onExpandSection?: (title: string) => void; + expand: boolean; + items: AccordionItemState[]; + setItems: (items: AccordionItemState[] | ((items) => AccordionItemState[])) => void; + onExpandSection?: (title: string) => void; }; diff --git a/src/components/AccordionItem/AccordionItem.scss b/src/components/AccordionItem/AccordionItem.scss index e7f7866..8b173a0 100644 --- a/src/components/AccordionItem/AccordionItem.scss +++ b/src/components/AccordionItem/AccordionItem.scss @@ -1,30 +1,29 @@ @import 'src/components/Accordion/Accordion.mixins'; .adv-accordion__item { - @include adv-accordion__item; + @include adv-accordion__item; } .adv-accordion__item--open { - @include adv-accordion__item--open; + @include adv-accordion__item--open; } .adv-accordion__header { - @include adv-accordion__header; + @include adv-accordion__header; } .adv-accordion__title-wrapper { - @include adv-accordion__title-wrapper; + @include adv-accordion__title-wrapper; } .adv-accordion__title { - @include adv-accordion__title; + @include adv-accordion__title; } - .adv-accordion__toggle { - @include adv-accordion__toggle; + @include adv-accordion__toggle; } .adv-accordion__content { - @include adv-accordion__content; + @include adv-accordion__content; } diff --git a/src/components/AccordionItem/AccordionItem.tsx b/src/components/AccordionItem/AccordionItem.tsx index c0283ca..c64ac17 100644 --- a/src/components/AccordionItem/AccordionItem.tsx +++ b/src/components/AccordionItem/AccordionItem.tsx @@ -9,49 +9,49 @@ import { AccordionItemState } from '../Accordion/types'; import './AccordionItem.scss'; export default function AccordionItem({ children, open = false, title = '' }: AccordionItemProps) { - const { expand, items, setItems, onExpandSection } = useAccordionContext(); - - const [isOpen, setIsOpen] = useState(open); - const [id] = useState(getUniqueId); - - const toggle = () => { - const newValue = !isOpen; - const newItems: AccordionItemState[] = [...items]; - if (!expand) { - setItems(newItems.map((item) => ({ ...item, isOpen: item.id === id ? newValue : false }))); - } else { - newItems.find((item) => item.id === id).isOpen = newValue; - setItems(newItems); - } - }; - - useEffect(() => { - setItems((items) => [...items, { id, isOpen }]); - }, []); - - useEffect(() => { - setIsOpen(open); - }, [open]); - - useEffect(() => { - setIsOpen(items.find((item) => item.id === id)?.isOpen); - }, [items]); - - useEffect(() => { - isOpen && onExpandSection?.(title); - }, [isOpen]); - - return ( -
-
- -
-
{title}
-
-
- -
{children}
-
+ const { expand, items, setItems, onExpandSection } = useAccordionContext(); + + const [isOpen, setIsOpen] = useState(open); + const [id] = useState(getUniqueId); + + const toggle = () => { + const newValue = !isOpen; + const newItems: AccordionItemState[] = [...items]; + if (!expand) { + setItems(newItems.map((item) => ({ ...item, isOpen: item.id === id ? newValue : false }))); + } else { + newItems.find((item) => item.id === id).isOpen = newValue; + setItems(newItems); + } + }; + + useEffect(() => { + setItems((items) => [...items, { id, isOpen }]); + }, []); + + useEffect(() => { + setIsOpen(open); + }, [open]); + + useEffect(() => { + setIsOpen(items.find((item) => item.id === id)?.isOpen); + }, [items]); + + useEffect(() => { + isOpen && onExpandSection?.(title); + }, [isOpen]); + + return ( +
+
+ +
+
{title}
- ); +
+ +
{children}
+
+
+ ); } diff --git a/src/components/AccordionItem/types.ts b/src/components/AccordionItem/types.ts index 34793fe..8de46ec 100644 --- a/src/components/AccordionItem/types.ts +++ b/src/components/AccordionItem/types.ts @@ -1,7 +1,7 @@ import { ComponentChildren } from 'preact'; export interface AccordionItemProps { - children: ComponentChildren; - open?: boolean; - title?: string; + children: ComponentChildren; + open?: boolean; + title?: string; } diff --git a/src/components/AccordionItem/useAccordionContext.ts b/src/components/AccordionItem/useAccordionContext.ts index 50842ce..4edab5e 100644 --- a/src/components/AccordionItem/useAccordionContext.ts +++ b/src/components/AccordionItem/useAccordionContext.ts @@ -2,7 +2,7 @@ import { useContext } from 'preact/hooks'; import { AccordionContext } from '../Accordion/AccordionContext'; function useAccordionContext() { - return useContext(AccordionContext); + return useContext(AccordionContext); } export default useAccordionContext; diff --git a/src/components/Chapter/Chapter.tsx b/src/components/Chapter/Chapter.tsx index 59f11c9..4fa33f4 100644 --- a/src/components/Chapter/Chapter.tsx +++ b/src/components/Chapter/Chapter.tsx @@ -5,12 +5,12 @@ import Text from '../Text/Text'; import ContentElements from '../ContentElements/ContentElements'; export default function Chapter({ title, contentElements }: ChapterProps) { - return ( -
- - - - -
- ); + return ( +
+ + + + +
+ ); } diff --git a/src/components/CollapsibleContainer/CollapsibleContainer.scss b/src/components/CollapsibleContainer/CollapsibleContainer.scss index 9703c7a..e72a8e8 100644 --- a/src/components/CollapsibleContainer/CollapsibleContainer.scss +++ b/src/components/CollapsibleContainer/CollapsibleContainer.scss @@ -1,8 +1,9 @@ @import '../../style/mixins'; .adv-collapsible-container { - @include adv-component-base; + @include adv-component-base; - overflow: hidden; - transition: height var(--adv-accordion-transition-duration) var(--adv-accordion-transition-function); + overflow: hidden; + transition: height var(--adv-accordion-transition-duration) + var(--adv-accordion-transition-function); } diff --git a/src/components/CollapsibleContainer/CollapsibleContainer.tsx b/src/components/CollapsibleContainer/CollapsibleContainer.tsx index 518a582..9c85148 100644 --- a/src/components/CollapsibleContainer/CollapsibleContainer.tsx +++ b/src/components/CollapsibleContainer/CollapsibleContainer.tsx @@ -3,18 +3,26 @@ import { CollapsibleContainerProps } from './types'; import { useEffect, useRef, useState } from 'preact/hooks'; import './CollapsibleContainer.scss'; -export default function CollapsibleContainer({ children, collapsed = false }: CollapsibleContainerProps) { - const collapsibleContainerEl = useRef(null); +export default function CollapsibleContainer({ + children, + collapsed = false, +}: CollapsibleContainerProps) { + const collapsibleContainerEl = useRef(null); - const [height, setHeight] = useState(collapsed ? 0 : undefined); + const [height, setHeight] = useState(collapsed ? 0 : undefined); - useEffect(() => { - setHeight(collapsed ? 0 : collapsibleContainerEl.current?.scrollHeight); - }, [collapsed]); + useEffect(() => { + setHeight(collapsed ? 0 : collapsibleContainerEl.current?.scrollHeight); + }, [collapsed]); - return ( -
- {children} -
- ); + return ( +
+ {children} +
+ ); } diff --git a/src/components/CollapsibleContainer/types.ts b/src/components/CollapsibleContainer/types.ts index 6deb61b..fac5728 100644 --- a/src/components/CollapsibleContainer/types.ts +++ b/src/components/CollapsibleContainer/types.ts @@ -1,6 +1,6 @@ import { ComponentChildren } from 'preact'; export interface CollapsibleContainerProps { - children: ComponentChildren; - collapsed?: boolean; + children: ComponentChildren; + collapsed?: boolean; } diff --git a/src/components/ContentElements/ContentElements.tsx b/src/components/ContentElements/ContentElements.tsx index 17d7613..9da6506 100644 --- a/src/components/ContentElements/ContentElements.tsx +++ b/src/components/ContentElements/ContentElements.tsx @@ -11,83 +11,87 @@ import List from '../ListElemennt/List'; import Table from '../Table/Table'; import InternalReference from '../InternalReference/InternalReference'; -export default function ContentElements({ contentElements, isTopLevel = false, onExpandSection }: ContentElementsProps) { - const components = { - chapter: Chapter, - section: Section, - paragraph: Paragraph, - text: Text, - weblink: Weblink, - list: List, - table: Table, - internalReference: InternalReference, - breakline: 'br' - }; +export default function ContentElements({ + contentElements, + isTopLevel = false, + onExpandSection, +}: ContentElementsProps) { + const components = { + chapter: Chapter, + section: Section, + paragraph: Paragraph, + text: Text, + weblink: Weblink, + list: List, + table: Table, + internalReference: InternalReference, + breakline: 'br', + }; - const getKey = (type: string) => `key-${type}-${getUniqueId()}`; + const getKey = (type: string) => `key-${type}-${getUniqueId()}`; - const getProps = (element): any => { - switch (element.type) { - case ElementTypes.Chapter: - return { - title: element.title, - contentElements: element.contentElements - }; - case ElementTypes.Section: - return { - isTopLevel, - title: element.title, - label: element.label, - contentElements: element.contentElements - }; - case ElementTypes.Paragraph: - return { - isTopLevel, - contentElements: element.contentElements - }; - case ElementTypes.Text: - return { - content: element.content, - styles: element.styles - }; - case ElementTypes.Weblink: - return { - url: element.url, - displayText: element.displayText - }; - case ElementTypes.List: - return { - items: element.items, - style: element.style - }; - case ElementTypes.Table: - return { - rows: element.rows, - label: element.label, - captions: element.captions, - titlePrefix: element.titlePrefix, - title: element.title - }; - case ElementTypes.InternalReference: - return { - referencedLabel: element.referencedLabel, - displayText: element.displayText - }; - default: - return null; - } - }; + const getProps = (element): any => { + switch (element.type) { + case ElementTypes.Chapter: + return { + title: element.title, + contentElements: element.contentElements, + }; + case ElementTypes.Section: + return { + isTopLevel, + title: element.title, + label: element.label, + contentElements: element.contentElements, + }; + case ElementTypes.Paragraph: + return { + isTopLevel, + contentElements: element.contentElements, + }; + case ElementTypes.Text: + return { + content: element.content, + styles: element.styles, + }; + case ElementTypes.Weblink: + return { + url: element.url, + displayText: element.displayText, + }; + case ElementTypes.List: + return { + items: element.items, + style: element.style, + }; + case ElementTypes.Table: + return { + rows: element.rows, + label: element.label, + captions: element.captions, + titlePrefix: element.titlePrefix, + title: element.title, + }; + case ElementTypes.InternalReference: + return { + referencedLabel: element.referencedLabel, + displayText: element.displayText, + }; + default: + return null; + } + }; - const elements = contentElements.map((contentElement): VNode => { - const Component = components[contentElement.type]; - return ; - }); + const elements = contentElements.map((contentElement): VNode => { + const Component = components[contentElement.type]; + return ; + }); - return isTopLevel ? ( - - {elements} - - ) : ( - {elements} - ); + return isTopLevel ? ( + + {elements} + + ) : ( + {elements} + ); } diff --git a/src/components/Heading/Heading.mixins.scss b/src/components/Heading/Heading.mixins.scss index 8ef6d32..06227c8 100644 --- a/src/components/Heading/Heading.mixins.scss +++ b/src/components/Heading/Heading.mixins.scss @@ -1,18 +1,18 @@ @import 'src/style/mixins'; @mixin adv-heading { - @include adv-component-base; + @include adv-component-base; - display: block; - font-size: var(--adv-heading-font-size); - font-weight: var(--adv-heading-font-weight); - line-height: var(--adv-heading-line-height); - margin: 0; - padding: 0; + display: block; + font-size: var(--adv-heading-font-size); + font-weight: var(--adv-heading-font-weight); + line-height: var(--adv-heading-line-height); + margin: 0; + padding: 0; } @mixin adv-heading--2 { - font-size: var(--adv-heading-2-font-size); - font-weight: var(--adv-heading-2-font-weight); - line-height: var(--adv-heading-2-line-height); + font-size: var(--adv-heading-2-font-size); + font-weight: var(--adv-heading-2-font-weight); + line-height: var(--adv-heading-2-line-height); } diff --git a/src/components/Heading/Heading.scss b/src/components/Heading/Heading.scss index bbe2ec9..150013b 100644 --- a/src/components/Heading/Heading.scss +++ b/src/components/Heading/Heading.scss @@ -1,9 +1,9 @@ @import 'Heading.mixins'; .adv-heading { - @include adv-heading; + @include adv-heading; } .adv-heading--2 { - @include adv-heading--2; + @include adv-heading--2; } diff --git a/src/components/Heading/Heading.tsx b/src/components/Heading/Heading.tsx index cb890c8..74f71d3 100644 --- a/src/components/Heading/Heading.tsx +++ b/src/components/Heading/Heading.tsx @@ -3,18 +3,18 @@ import cx from 'classnames'; import './Heading.scss'; export interface HeadingProps { - children: ComponentChildren | string; - level: 1 | 2; - className?: string; + children: ComponentChildren | string; + level: 1 | 2; + className?: string; } const headingTypes = { - 1: 'h1', - 2: 'h2' + 1: 'h1', + 2: 'h2', }; export default function Heading({ className, level, children }: HeadingProps) { - const tagName = headingTypes[level] || headingTypes[1]; - const classNames = cx('adv-heading', `adv-heading--${level}`, className); - return createElement(tagName, { className: classNames }, children); + const tagName = headingTypes[level] || headingTypes[1]; + const classNames = cx('adv-heading', `adv-heading--${level}`, className); + return createElement(tagName, { className: classNames }, children); } diff --git a/src/components/Icon/Icon.scss b/src/components/Icon/Icon.scss index 6d90b85..0e20521 100644 --- a/src/components/Icon/Icon.scss +++ b/src/components/Icon/Icon.scss @@ -1,14 +1,14 @@ .adv-icon { - display: inline-block; - fill: var(--adv-icon-color); - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - font-style: normal; - font-variant: normal; - font-weight: normal; - line-height: 1; - position: relative; - speak: none; - text-transform: none; - vertical-align: baseline; + display: inline-block; + fill: var(--adv-icon-color); + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + font-style: normal; + font-variant: normal; + font-weight: normal; + line-height: 1; + position: relative; + speak: none; + text-transform: none; + vertical-align: baseline; } diff --git a/src/components/Icon/Icon.tsx b/src/components/Icon/Icon.tsx index 9544c92..98213dc 100644 --- a/src/components/Icon/Icon.tsx +++ b/src/components/Icon/Icon.tsx @@ -3,35 +3,35 @@ import cx from 'classnames'; import './Icon.scss'; interface IconProps { - name: string; - className?: string; + name: string; + className?: string; } const Icon = ({ className = '', name }: IconProps) => { - const iconTypes = { - 'chevron-up': ( - - - - ), - 'chevron-down': ( - - - - ) - }; + const iconTypes = { + 'chevron-up': ( + + + + ), + 'chevron-down': ( + + + + ), + }; - return ( - - {iconTypes[name]} - - ); + return ( + + {iconTypes[name]} + + ); }; export default Icon; diff --git a/src/components/InternalReference/InternalReference.tsx b/src/components/InternalReference/InternalReference.tsx index 1113d63..636a5cb 100644 --- a/src/components/InternalReference/InternalReference.tsx +++ b/src/components/InternalReference/InternalReference.tsx @@ -3,14 +3,17 @@ import { InternalReferenceProps } from '../../types'; import LinkButton from '../LinkButton/LinkButton'; import { getScrollParent } from '../../utils/scroll'; -export default function InternalReference({ referencedLabel, displayText }: InternalReferenceProps) { - const label = displayText ? displayText.content : referencedLabel; +export default function InternalReference({ + referencedLabel, + displayText, +}: InternalReferenceProps) { + const label = displayText ? displayText.content : referencedLabel; - const scrollIntoView = () => { - const scrollParent = getScrollParent(document.getElementById(referencedLabel)); - const element = scrollParent !== -1 && scrollParent.querySelector('#' + referencedLabel); - element?.scrollIntoView({ behavior: 'smooth' }); - }; + const scrollIntoView = () => { + const scrollParent = getScrollParent(document.getElementById(referencedLabel)); + const element = scrollParent !== -1 && scrollParent.querySelector('#' + referencedLabel); + element?.scrollIntoView({ behavior: 'smooth' }); + }; - return ; + return ; } diff --git a/src/components/Link/Link.mixins.scss b/src/components/Link/Link.mixins.scss index ad3500f..fca4c6c 100755 --- a/src/components/Link/Link.mixins.scss +++ b/src/components/Link/Link.mixins.scss @@ -1,63 +1,63 @@ @import 'src/style/mixins'; @mixin adv-link { - @include adv-component-base; - - background-color: var(--adv-link-background-color); - border: 0; - color: var(--adv-link-color); - cursor: pointer; - display: inline; - padding: 0; - text-decoration: var(--adv-link-text-decoration); - vertical-align: baseline; - - &:hover { - text-decoration: var(--adv-link-hover-text-decoration); - } - - &:active { - color: var(--adv-link-active-color); - } - - &:focus { - outline: var(--adv-link-focus-outline); - text-decoration: var(--adv-link-hover-text-decoration); - } - - &:visited { - color: var(--adv-link-visited-color); - } + @include adv-component-base; + + background-color: var(--adv-link-background-color); + border: 0; + color: var(--adv-link-color); + cursor: pointer; + display: inline; + padding: 0; + text-decoration: var(--adv-link-text-decoration); + vertical-align: baseline; + + &:hover { + text-decoration: var(--adv-link-hover-text-decoration); + } + + &:active { + color: var(--adv-link-active-color); + } + + &:focus { + outline: var(--adv-link-focus-outline); + text-decoration: var(--adv-link-hover-text-decoration); + } + + &:visited { + color: var(--adv-link-visited-color); + } } @mixin adv-link--inherit { - &, - &:hover, - &:active, - &:visited { - color: var(--adv-link-inherit-color); - font-size: var(--adv-link-inherit-font-size); - font-weight: inherit; - } + &, + &:hover, + &:active, + &:visited { + color: var(--adv-link-inherit-color); + font-size: var(--adv-link-inherit-font-size); + font-weight: inherit; + } } @mixin adv-link--underline { - text-decoration: underline; + text-decoration: underline; - &, - &:active, - &:visited { - color: var(--adv-link-underline-color); - } + &, + &:active, + &:visited { + color: var(--adv-link-underline-color); + } - &:hover { - color: var(--adv-text-color); - } + &:hover { + color: var(--adv-text-color); + } } @mixin adv-link__text { - @include adv-link--inherit; + @include adv-link--inherit; - display: inline; - vertical-align: baseline; + display: inline; + vertical-align: baseline; } diff --git a/src/components/Link/Link.scss b/src/components/Link/Link.scss index cea7fd8..1c97d0c 100755 --- a/src/components/Link/Link.scss +++ b/src/components/Link/Link.scss @@ -1,5 +1,5 @@ @import 'Link.mixins'; .adv-link { - @include adv-link; + @include adv-link; } diff --git a/src/components/Link/Link.tsx b/src/components/Link/Link.tsx index 18627ee..3469c60 100644 --- a/src/components/Link/Link.tsx +++ b/src/components/Link/Link.tsx @@ -3,17 +3,30 @@ import cx from 'classnames'; import './Link.scss'; import LinkProps from './types'; -const Link: FunctionalComponent = ({ className, children, href, underline, inheritStyles, onClick }) => { - const classNames = cx('adv-link', className, { - 'adv-link--underline': underline, - 'adv-link--inherit': inheritStyles - }); +const Link: FunctionalComponent = ({ + className, + children, + href, + underline, + inheritStyles, + onClick, +}) => { + const classNames = cx('adv-link', className, { + 'adv-link--underline': underline, + 'adv-link--inherit': inheritStyles, + }); - return ( - - {children} - - ); + return ( + + {children} + + ); }; export default Link; diff --git a/src/components/Link/types.ts b/src/components/Link/types.ts index a9a054b..4dd6868 100644 --- a/src/components/Link/types.ts +++ b/src/components/Link/types.ts @@ -1,10 +1,10 @@ import { h } from 'preact'; export default interface LinkProps { - href: string; // Required - links with no `href` are not accessible - className?: string; + href: string; // Required - links with no `href` are not accessible + className?: string; - inheritStyles?: boolean; - underline?: boolean; - onClick?: h.JSX.MouseEventHandler; + inheritStyles?: boolean; + underline?: boolean; + onClick?: h.JSX.MouseEventHandler; } diff --git a/src/components/LinkButton/LinkButton.tsx b/src/components/LinkButton/LinkButton.tsx index 521d8cd..66b96e7 100644 --- a/src/components/LinkButton/LinkButton.tsx +++ b/src/components/LinkButton/LinkButton.tsx @@ -3,14 +3,14 @@ import { h } from 'preact'; import '../Link/Link.scss'; interface LinkButtonProps { - onClick?: () => void; - label?: string; + onClick?: () => void; + label?: string; } const LinkButton = ({ onClick, label }: LinkButtonProps) => ( - + ); export default LinkButton; diff --git a/src/components/List/List.mixins.scss b/src/components/List/List.mixins.scss index 6471b05..df79a44 100755 --- a/src/components/List/List.mixins.scss +++ b/src/components/List/List.mixins.scss @@ -1,37 +1,37 @@ @import 'src/style/mixins'; @mixin adv-list { - @include adv-component-base; + @include adv-component-base; - display: block; - list-style-position: outside; - list-style-type: disc; - margin: var(--adv-list-margin); - padding: var(--adv-list-padding); + display: block; + list-style-position: outside; + list-style-type: disc; + margin: var(--adv-list-margin); + padding: var(--adv-list-padding); } @mixin adv-list--ordered { - list-style-type: decimal; + list-style-type: decimal; } @mixin adv-list--nested { - list-style-type: circle; - padding: var(--adv-list-nested-padding); + list-style-type: circle; + padding: var(--adv-list-nested-padding); } @mixin adv-list__item { - padding: var(--adv-list-item-padding); + padding: var(--adv-list-item-padding); } @mixin adv-list__item--no-marker { - list-style: var(--adv-list-no-markers-list-style); + list-style: var(--adv-list-no-markers-list-style); } @mixin adv-list--no-markers { - list-style: var(--adv-list-no-markers-list-style); - padding: var(--adv-list-no-markers-padding); + list-style: var(--adv-list-no-markers-list-style); + padding: var(--adv-list-no-markers-padding); - .adv-list__item { - padding-left: 0; - } + .adv-list__item { + padding-left: 0; + } } diff --git a/src/components/List/List.scss b/src/components/List/List.scss index 0b8ae16..3aff0b9 100755 --- a/src/components/List/List.scss +++ b/src/components/List/List.scss @@ -1,25 +1,25 @@ @import 'List.mixins'; .adv-list { - @include adv-list; + @include adv-list; } .adv-list--no-markers { - @include adv-list--no-markers; + @include adv-list--no-markers; } .adv-list__item { - @include adv-list__item; + @include adv-list__item; } .adv-list__item--no-marker { - @include adv-list__item--no-marker; + @include adv-list__item--no-marker; } .adv-list--nested { - @include adv-list--nested; + @include adv-list--nested; } .adv-list--ordered { - @include adv-list--ordered; + @include adv-list--ordered; } diff --git a/src/components/List/List.tsx b/src/components/List/List.tsx index 2a812ff..52fb4bd 100644 --- a/src/components/List/List.tsx +++ b/src/components/List/List.tsx @@ -4,8 +4,14 @@ import './List.scss'; import { ListProps } from './types'; function List({ className, nested, ordered, noMarkers, children }: ListProps) { - const classNames = cx(['adv-list', nested && 'adv-list--nested', ordered && 'adv-list--ordered', noMarkers && 'adv-list--no-markers', className]); - return
    {children}
; + const classNames = cx([ + 'adv-list', + nested && 'adv-list--nested', + ordered && 'adv-list--ordered', + noMarkers && 'adv-list--no-markers', + className, + ]); + return
    {children}
; } export default List; diff --git a/src/components/List/ListItem.tsx b/src/components/List/ListItem.tsx index 8032d9d..d144731 100644 --- a/src/components/List/ListItem.tsx +++ b/src/components/List/ListItem.tsx @@ -3,9 +3,9 @@ import cx from 'classnames'; import { ListItemProps } from './types'; function ListItem({ className, children, noMarkers }: ListItemProps) { - const classNames = cx(['adv-list__item', noMarkers && 'adv-list__item--no-markers', className]); + const classNames = cx(['adv-list__item', noMarkers && 'adv-list__item--no-markers', className]); - return
  • {children}
  • ; + return
  • {children}
  • ; } export default ListItem; diff --git a/src/components/List/types.ts b/src/components/List/types.ts index 489c1e0..8033ab8 100644 --- a/src/components/List/types.ts +++ b/src/components/List/types.ts @@ -1,15 +1,15 @@ import { ComponentChildren } from 'preact'; export interface ListItemProps { - children?: ComponentChildren; - className?: string; - noMarkers?: boolean; + children?: ComponentChildren; + className?: string; + noMarkers?: boolean; } export interface ListProps { - children?: ComponentChildren; - className?: string; - nested?: boolean; - ordered?: boolean; - noMarkers?: boolean; + children?: ComponentChildren; + className?: string; + nested?: boolean; + ordered?: boolean; + noMarkers?: boolean; } diff --git a/src/components/ListElemennt/List.tsx b/src/components/ListElemennt/List.tsx index c40531c..ac814b8 100644 --- a/src/components/ListElemennt/List.tsx +++ b/src/components/ListElemennt/List.tsx @@ -5,14 +5,14 @@ import ListItem from '../List/ListItem'; import ContentElements from '../ContentElements/ContentElements'; export default function ListElement({ items, style }: ListProps) { - return ( - - {items.map((item, index) => ( - - - {item.subList && } - - ))} - - ); + return ( + + {items.map((item, index) => ( + + + {item.subList && } + + ))} + + ); } diff --git a/src/components/Paragraph/Paragraph.scss b/src/components/Paragraph/Paragraph.scss index 5297b2d..bebbb96 100644 --- a/src/components/Paragraph/Paragraph.scss +++ b/src/components/Paragraph/Paragraph.scss @@ -1,12 +1,12 @@ @import 'src/style/mixins'; .adv-paragraph { - @include adv-component-base; + @include adv-component-base; - margin-bottom: 0; - margin-top: 0; + margin-bottom: 0; + margin-top: 0; - &:not(:first-child) { - margin-top: var(--adv-spacing-16); - } + &:not(:first-child) { + margin-top: var(--adv-spacing-16); + } } diff --git a/src/components/Paragraph/Paragraph.tsx b/src/components/Paragraph/Paragraph.tsx index 167858a..5bfcd62 100644 --- a/src/components/Paragraph/Paragraph.tsx +++ b/src/components/Paragraph/Paragraph.tsx @@ -5,13 +5,13 @@ import cx from 'classnames'; import './Paragraph.scss'; export default function Paragraph({ isTopLevel, contentElements }: ParagraphProps) { - const classNames = cx('adv-paragraph', { - 'adv-u-margin-bottom-16': isTopLevel - }); + const classNames = cx('adv-paragraph', { + 'adv-u-margin-bottom-16': isTopLevel, + }); - return ( -

    - -

    - ); + return ( +

    + +

    + ); } diff --git a/src/components/Section/Section.scss b/src/components/Section/Section.scss index 32a52fb..5a4526e 100644 --- a/src/components/Section/Section.scss +++ b/src/components/Section/Section.scss @@ -1,6 +1,6 @@ .adv-section-box { - background-color: var(--adv-section-background-color); - border-radius: var(--adv-section-border-radius); - margin: var(--adv-section-margin); - padding: var(--adv-section-padding); + background-color: var(--adv-section-background-color); + border-radius: var(--adv-section-border-radius); + margin: var(--adv-section-margin); + padding: var(--adv-section-padding); } diff --git a/src/components/Section/Section.tsx b/src/components/Section/Section.tsx index 88dc18b..cd447e3 100644 --- a/src/components/Section/Section.tsx +++ b/src/components/Section/Section.tsx @@ -7,18 +7,18 @@ import AccordionItem from '../AccordionItem/AccordionItem'; import ContentElements from '../ContentElements/ContentElements'; export default function Section({ title, label, isTopLevel, contentElements }: SectionProps) { - return isTopLevel ? ( - -
    - -
    -
    - ) : ( -
    - - - - -
    - ); + return isTopLevel ? ( + +
    + +
    +
    + ) : ( +
    + + + + +
    + ); } diff --git a/src/components/Table/Table.mixins.scss b/src/components/Table/Table.mixins.scss index ee8c025..02ce548 100644 --- a/src/components/Table/Table.mixins.scss +++ b/src/components/Table/Table.mixins.scss @@ -1,63 +1,63 @@ @import 'src/style/mixins'; @mixin adv-table { - @include adv-component-base; + @include adv-component-base; - border: var(--adv-table-border); - border-collapse: collapse; - border-spacing: 0; - line-height: var(--adv-table-line-height); - margin: var(--adv-table-margin); - padding: var(--adv-table-padding); - text-align: left; - width: var(--adv-table-width); + border: var(--adv-table-border); + border-collapse: collapse; + border-spacing: 0; + line-height: var(--adv-table-line-height); + margin: var(--adv-table-margin); + padding: var(--adv-table-padding); + text-align: left; + width: var(--adv-table-width); } -@mixin adv-table--condensed ( - $cell-selector: '.adv-table__cell', - $checkbox-cell-selector: '.adv-table__checkbox-cell') { - #{$cell-selector} { - font-size: var(--adv-table-condensed-font-size); - padding: var(--adv-table-condensed-cell-padding); - } - +@mixin adv-table--condensed( + $cell-selector: '.adv-table__cell', + $checkbox-cell-selector: '.adv-table__checkbox-cell' +) { + #{$cell-selector} { + font-size: var(--adv-table-condensed-font-size); + padding: var(--adv-table-condensed-cell-padding); + } } @mixin adv-table-vertical-align { - vertical-align: var(--adv-table-vertical-align); + vertical-align: var(--adv-table-vertical-align); } -@mixin adv-table__body ($row-element: '.adv-table__row') { - @include adv-table-vertical-align; +@mixin adv-table__body($row-element: '.adv-table__row') { + @include adv-table-vertical-align; - #{$row-element}:hover { - @include adv-table__row--changed; - } + #{$row-element}:hover { + @include adv-table__row--changed; + } } @mixin adv-table__row { - @include adv-table-vertical-align; + @include adv-table-vertical-align; - border-bottom: var(--adv-table-row-border); + border-bottom: var(--adv-table-row-border); } @mixin adv-table__row--changed { - background-color: var(--adv-table-row-changed-background-color); + background-color: var(--adv-table-row-changed-background-color); } @mixin adv-table__cell--first-column { - padding-left: var(--adv-table-first-column-padding-left); + padding-left: var(--adv-table-first-column-padding-left); } @mixin adv-table__cell { - border-left: var(--adv-border-width) solid transparent; - border-right: var(--adv-border-width) solid transparent; - overflow: auto; - padding: var(--adv-table-cell-padding); - text-align: var(--adv-table-cell-text-align); - vertical-align: inherit; - - &:first-child { - @include adv-table__cell--first-column; - } + border-left: var(--adv-border-width) solid transparent; + border-right: var(--adv-border-width) solid transparent; + overflow: auto; + padding: var(--adv-table-cell-padding); + text-align: var(--adv-table-cell-text-align); + vertical-align: inherit; + + &:first-child { + @include adv-table__cell--first-column; + } } diff --git a/src/components/Table/Table.scss b/src/components/Table/Table.scss index 3c4da91..3222e65 100755 --- a/src/components/Table/Table.scss +++ b/src/components/Table/Table.scss @@ -1,29 +1,29 @@ @import 'Table.mixins'; .adv-table { - @include adv-table; + @include adv-table; } .adv-table--condensed { - @include adv-table--condensed; + @include adv-table--condensed; } .adv-table__row { - @include adv-table__row; + @include adv-table__row; } .adv-table__row--changed { - @include adv-table__row--changed; + @include adv-table__row--changed; } .adv-table__body { - @include adv-table__body; + @include adv-table__body; } .adv-table__cell { - @include adv-table__cell; + @include adv-table__cell; } .adv-table__cell--first-column { - @include adv-table__cell--first-column; + @include adv-table__cell--first-column; } diff --git a/src/components/Table/Table.tsx b/src/components/Table/Table.tsx index 3478101..71b7a02 100644 --- a/src/components/Table/Table.tsx +++ b/src/components/Table/Table.tsx @@ -5,31 +5,31 @@ import ContentElements from '../ContentElements/ContentElements'; import './Table.scss'; export default function Table({ rows, label, captions, titlePrefix, title }: TableProps) { - return ( -
    -
    - {titlePrefix && } - {title && } -
    + return ( +
    +
    + {titlePrefix && } + {title && } +
    - - {captions && ( - - )} - - {rows.map((row, rowIndex) => ( - - {row.map((cell, cellIndex) => ( - - ))} - - ))} - -
    - -
    - -
    -
    - ); + + {captions && ( + + )} + + {rows.map((row, rowIndex) => ( + + {row.map((cell, cellIndex) => ( + + ))} + + ))} + +
    + +
    + +
    +
    + ); } diff --git a/src/components/Text/Text.tsx b/src/components/Text/Text.tsx index 7096933..3d38db0 100644 --- a/src/components/Text/Text.tsx +++ b/src/components/Text/Text.tsx @@ -3,10 +3,10 @@ import { TextProps, TextStyle } from '../../types'; import cx from 'classnames'; export default function Text({ content, styles }: TextProps) { - const classNames = cx({ - 'adv-u-font-weight-semi-bold': styles?.includes(TextStyle.Bold), - 'adv-u-font-italic': styles?.includes(TextStyle.Italic) - }); + const classNames = cx({ + 'adv-u-font-weight-semi-bold': styles?.includes(TextStyle.Bold), + 'adv-u-font-italic': styles?.includes(TextStyle.Italic), + }); - return {content}; + return {content}; } diff --git a/src/components/Weblink/Weblink.tsx b/src/components/Weblink/Weblink.tsx index 08e0bff..04de5b9 100644 --- a/src/components/Weblink/Weblink.tsx +++ b/src/components/Weblink/Weblink.tsx @@ -3,6 +3,8 @@ import { WeblinkProps } from '../../types'; import Text from '../Text/Text'; import Link from '../Link/Link'; -const Weblink = ({ url, displayText }: WeblinkProps) => {displayText ? : url}; +const Weblink = ({ url, displayText }: WeblinkProps) => ( + {displayText ? : url} +); export default Weblink; diff --git a/src/index.tsx b/src/index.tsx index e8bd1fe..4419e80 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,34 +1,34 @@ if (process.env.NODE_ENV === 'development') { - require('preact/debug'); + require('preact/debug'); } import { h, render } from 'preact'; import DocumentViewer from './DocumentViewer'; export default class AdyenDocumentViewer { - private readonly target: HTMLElement; + private readonly target: HTMLElement; - /** - * Initializes the library - * @param target - The target element (HTMLElement or querySelector string) - */ - constructor(target: HTMLElement | string) { - if (typeof target === 'object' && 'nodeType' in target) { - this.target = target; - } else { - try { - this.target = window.document.querySelector(target); - if (!this.target) throw Error('Target element was not found'); - } catch (e) { - throw Error(e); - } - } + /** + * Initializes the library + * @param target - The target element (HTMLElement or querySelector string) + */ + constructor(target: HTMLElement | string) { + if (typeof target === 'object' && 'nodeType' in target) { + this.target = target; + } else { + try { + this.target = window.document.querySelector(target); + if (!this.target) throw Error('Target element was not found'); + } catch (e) { + throw Error(e); + } } + } - /** - * Renders the document - * @param document - The JSON document - */ - render(document: JSON): void { - render(, this.target); - } + /** + * Renders the document + * @param document - The JSON document + */ + render(document: JSON): void { + render(, this.target); + } } diff --git a/src/style/mixins.scss b/src/style/mixins.scss index b370438..fc594a5 100644 --- a/src/style/mixins.scss +++ b/src/style/mixins.scss @@ -1,21 +1,22 @@ @mixin adv-component-base { - color: var(--adv-text-color); - font-family: var(--adv-text-font-family); - font-size: var(--adv-text-font-size-medium); - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - font-weight: var(--adv-text-font-weight-regular); - line-height: var(--adv-text-line-height); + color: var(--adv-text-color); + font-family: var(--adv-text-font-family); + font-size: var(--adv-text-font-size-medium); + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + font-weight: var(--adv-text-font-weight-regular); + line-height: var(--adv-text-line-height); - *, - *::before, - *::after { - box-sizing: border-box; - } + *, + *::before, + *::after { + box-sizing: border-box; + } } @mixin adv-focus-ring { - box-shadow: 0 0 0 var(--adv-focus-ring-distance) var(--adv-focus-ring-background-color), 0 0 0 var(--adv-focus-ring-width) var(--adv-focus-ring-color); - transition: var(--adv-focus-ring-transition-duration) var(--adv-focus-ring-timing-function); - transition-property: box-shadow; + box-shadow: 0 0 0 var(--adv-focus-ring-distance) var(--adv-focus-ring-background-color), + 0 0 0 var(--adv-focus-ring-width) var(--adv-focus-ring-color); + transition: var(--adv-focus-ring-transition-duration) var(--adv-focus-ring-timing-function); + transition-property: box-shadow; } diff --git a/src/style/utilities/alignment.scss b/src/style/utilities/alignment.scss index f0c747c..fe985fb 100755 --- a/src/style/utilities/alignment.scss +++ b/src/style/utilities/alignment.scss @@ -1,3 +1,3 @@ .adv-u-text-align-center { - text-align: center !important; + text-align: center !important; } diff --git a/src/style/utilities/spacing.scss b/src/style/utilities/spacing.scss index b10850a..3adfb4a 100644 --- a/src/style/utilities/spacing.scss +++ b/src/style/utilities/spacing.scss @@ -1,16 +1,16 @@ .adv-u-margin-bottom-16 { - margin-bottom: var(--adv-spacing-16) !important; + margin-bottom: var(--adv-spacing-16) !important; } .adv-u-margin-bottom-48 { - margin-bottom: var(--adv-spacing-48) !important; + margin-bottom: var(--adv-spacing-48) !important; } .adv-u-margin-top-24 { - margin-top: var(--adv-spacing-24) !important; + margin-top: var(--adv-spacing-24) !important; } .adv-u-margin-y-8 { - margin-bottom: var(--adv-spacing-8) !important; - margin-top: var(--adv-spacing-8) !important; + margin-bottom: var(--adv-spacing-8) !important; + margin-top: var(--adv-spacing-8) !important; } diff --git a/src/style/utilities/typography.scss b/src/style/utilities/typography.scss index 2d87858..4bc02d0 100644 --- a/src/style/utilities/typography.scss +++ b/src/style/utilities/typography.scss @@ -1,11 +1,11 @@ .adv-u-font-weight-regular { - font-weight: var(--adv-text-font-weight-regular) !important; + font-weight: var(--adv-text-font-weight-regular) !important; } .adv-u-font-weight-semi-bold { - font-weight: var(--adv-text-font-weight-semi-bold) !important; + font-weight: var(--adv-text-font-weight-semi-bold) !important; } .adv-u-font-italic { - font-style: italic !important; + font-style: italic !important; } diff --git a/src/style/variables.scss b/src/style/variables.scss index b4cfa5f..6cce0b3 100644 --- a/src/style/variables.scss +++ b/src/style/variables.scss @@ -1,136 +1,142 @@ .adyen-document-viewer { - /* Colors */ - --adv-color-white: #fff; // backgrounds - --adv-color-black: #00112c; // text color - --adv-color-grey-10: #f3f6f9; // background, hover - --adv-color-grey-20: #dce0e5; // borders, active - --adv-color-blue: #06f; // links + /* Colors */ + --adv-color-white: #fff; // backgrounds + --adv-color-black: #00112c; // text color + --adv-color-grey-10: #f3f6f9; // background, hover + --adv-color-grey-20: #dce0e5; // borders, active + --adv-color-blue: #06f; // links - /* Background */ - --adv-background-color: var(--adv-color-white); + /* Background */ + --adv-background-color: var(--adv-color-white); - /* Fonts */ - --adv-text-font-family: -apple-system, blinkmacsystemfont, 'Segoe UI', roboto, oxygen, ubuntu, cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; - --adv-text-color: var(--adv-color-black); - --adv-text-font-weight-regular: 400; - --adv-text-font-weight-semi-bold: 600; - --adv-text-line-height: 1.4; - --adv-text-font-size-medium: 15px; - --adv-text-font-size-small: 13px; + /* Fonts */ + --adv-text-font-family: -apple-system, blinkmacsystemfont, 'Segoe UI', roboto, oxygen, ubuntu, + cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; + --adv-text-color: var(--adv-color-black); + --adv-text-font-weight-regular: 400; + --adv-text-font-weight-semi-bold: 600; + --adv-text-line-height: 1.4; + --adv-text-font-size-medium: 15px; + --adv-text-font-size-small: 13px; - /* Borders */ - --adv-border-width: 1px; - --adv-border-style: solid; - --adv-border-color: var(--adv-color-grey-20); - --adv-border-radius: 6px; + /* Borders */ + --adv-border-width: 1px; + --adv-border-style: solid; + --adv-border-color: var(--adv-color-grey-20); + --adv-border-radius: 6px; - /* Transition */ - --adv-transition-duration: 0.1s; - --adv-transition-function: cubic-bezier(0.785, 0.135, 0.15, 0.86); + /* Transition */ + --adv-transition-duration: 0.1s; + --adv-transition-function: cubic-bezier(0.785, 0.135, 0.15, 0.86); - /* Focus ring */ - --adv-focus-ring-transition-duration: var(--adv-transition-duration); - --adv-focus-ring-timing-function: var(--adv-transition-function); - --adv-focus-ring-color: rgba(0, 102, 255, 0.4); - --adv-focus-ring-distance: 1px; - --adv-focus-ring-width: 3px; - --adv-focus-ring-z-index: 1; - --adv-focus-ring-background-color: var(--adv-color-white); + /* Focus ring */ + --adv-focus-ring-transition-duration: var(--adv-transition-duration); + --adv-focus-ring-timing-function: var(--adv-transition-function); + --adv-focus-ring-color: rgba(0, 102, 255, 0.4); + --adv-focus-ring-distance: 1px; + --adv-focus-ring-width: 3px; + --adv-focus-ring-z-index: 1; + --adv-focus-ring-background-color: var(--adv-color-white); - /* Spacing */ - --adv-spacing-0: 0; - --adv-spacing-2: 2px; - --adv-spacing-4: 4px; - --adv-spacing-8: 8px; - --adv-spacing-12: 12px; - --adv-spacing-16: 16px; - --adv-spacing-24: 24px; - --adv-spacing-32: 32px; - --adv-spacing-40: 40px; - --adv-spacing-48: 48px; + /* Spacing */ + --adv-spacing-0: 0; + --adv-spacing-2: 2px; + --adv-spacing-4: 4px; + --adv-spacing-8: 8px; + --adv-spacing-12: 12px; + --adv-spacing-16: 16px; + --adv-spacing-24: 24px; + --adv-spacing-32: 32px; + --adv-spacing-40: 40px; + --adv-spacing-48: 48px; - /* Accordion */ - --adv-accordion-border-radius: var(--adv-border-radius); - --adv-accordion-item-border-color: var(--adv-border-color); - --adv-accordion-item-border-width: var(--adv-border-width); - --adv-accordion-between-items-border-color: transparent; - --adv-accordion-header-color: var(--adv-color-black); - --adv-accordion-header-padding: var(--adv-spacing-16); - --adv-accordion-header-font-weight: var(--adv-text-font-weight-semi-bold); - --adv-accordion-header-hover-background-color: var(--adv-color-grey-10); - --adv-accordion-header-active-background-color: var(--adv-color-grey-20); - --adv-accordion-header-border-radius: var(--adv-spacing-4); - --adv-accordion-title-color: inherit; - --adv-accordion-toggle-margin: var(--adv-spacing-2) var(--adv-spacing-16) 0 0; - --adv-accordion-toggle-padding: 0; - --adv-accordion-toggle-width: var(--adv-spacing-12); - --adv-accordion-content-margin: 0 0 var(--adv-spacing-24); - --adv-accordion-content-padding: 0 var(--adv-spacing-16) 0 calc(var(--adv-spacing-32) + var(--adv-spacing-12)); - --adv-accordion-content-closed-margin: 0; - --adv-accordion-transition-duration: var(--adv-transition-duration); - --adv-accordion-transition-function: var(--adv-transition-function); - --adv-accordion-transition-property: margin, height, padding; - --adv-accordion-css-animated-max-height: 500px; - --adv-accordion-css-animated-transition-duration: var(--adv-accordion-transition-duration); - --adv-accordion-css-animated-transition-property: margin, max-height; + /* Accordion */ + --adv-accordion-border-radius: var(--adv-border-radius); + --adv-accordion-item-border-color: var(--adv-border-color); + --adv-accordion-item-border-width: var(--adv-border-width); + --adv-accordion-between-items-border-color: transparent; + --adv-accordion-header-color: var(--adv-color-black); + --adv-accordion-header-padding: var(--adv-spacing-16); + --adv-accordion-header-font-weight: var(--adv-text-font-weight-semi-bold); + --adv-accordion-header-hover-background-color: var(--adv-color-grey-10); + --adv-accordion-header-active-background-color: var(--adv-color-grey-20); + --adv-accordion-header-border-radius: var(--adv-spacing-4); + --adv-accordion-title-color: inherit; + --adv-accordion-toggle-margin: var(--adv-spacing-2) var(--adv-spacing-16) 0 0; + --adv-accordion-toggle-padding: 0; + --adv-accordion-toggle-width: var(--adv-spacing-12); + --adv-accordion-content-margin: 0 0 var(--adv-spacing-24); + --adv-accordion-content-padding: 0 var(--adv-spacing-16) 0 + calc(var(--adv-spacing-32) + var(--adv-spacing-12)); + --adv-accordion-content-closed-margin: 0; + --adv-accordion-transition-duration: var(--adv-transition-duration); + --adv-accordion-transition-function: var(--adv-transition-function); + --adv-accordion-transition-property: margin, height, padding; + --adv-accordion-css-animated-max-height: 500px; + --adv-accordion-css-animated-transition-duration: var(--adv-accordion-transition-duration); + --adv-accordion-css-animated-transition-property: margin, max-height; - /* Heading */ - --adv-heading-font-size: 32px; - --adv-heading-font-weight: var(--adv-text-font-weight-semi-bold); - --adv-heading-line-height: 40px; - --adv-heading-2-font-size: 24px; - --adv-heading-2-font-weight: var(--adv-text-font-weight-semi-bold); - --adv-heading-2-line-height: 32px; + /* Heading */ + --adv-heading-font-size: 32px; + --adv-heading-font-weight: var(--adv-text-font-weight-semi-bold); + --adv-heading-line-height: 40px; + --adv-heading-2-font-size: 24px; + --adv-heading-2-font-weight: var(--adv-text-font-weight-semi-bold); + --adv-heading-2-line-height: 32px; - /* Icon */ - --adv-icon-color: var(--adv-color-black); + /* Icon */ + --adv-icon-color: var(--adv-color-black); - /* Link */ - --adv-link-color: var(--adv-color-blue); - --adv-link-background-color: transparent; - --adv-link-text-decoration: none; - --adv-link-hover-text-decoration: underline; - --adv-link-active-color: var(--adv-link-color); - --adv-link-focus-outline: none; - --adv-link-visited-color: var(--adv-link-color); - --adv-link-inherit-font-size: inherit; - --adv-link-inherit-color: inherit; - --adv-link-underline-color: inherit; + /* Link */ + --adv-link-color: var(--adv-color-blue); + --adv-link-background-color: transparent; + --adv-link-text-decoration: none; + --adv-link-hover-text-decoration: underline; + --adv-link-active-color: var(--adv-link-color); + --adv-link-focus-outline: none; + --adv-link-visited-color: var(--adv-link-color); + --adv-link-inherit-font-size: inherit; + --adv-link-inherit-color: inherit; + --adv-link-underline-color: inherit; - /* List */ - --adv-list-margin: 0; - --adv-list-padding: 0 0 0 18px; - --adv-list-nested-padding: var(--adv-list-padding); - --adv-list-item-padding: 0 0 0 var(--adv-spacing-4); - --adv-list-no-markers-padding: 0; - --adv-list-no-markers-list-style: none; + /* List */ + --adv-list-margin: 0; + --adv-list-padding: 0 0 0 18px; + --adv-list-nested-padding: var(--adv-list-padding); + --adv-list-item-padding: 0 0 0 var(--adv-spacing-4); + --adv-list-no-markers-padding: 0; + --adv-list-no-markers-list-style: none; - /* Section */ - --adv-section-background-color: var(--adv-color-grey-10); - --adv-section-border-radius: var(--adv-border-radius); - --adv-section-margin: var(--adv-spacing-24) 0 0 0; - --adv-section-padding: var(--adv-spacing-16); + /* Section */ + --adv-section-background-color: var(--adv-color-grey-10); + --adv-section-border-radius: var(--adv-border-radius); + --adv-section-margin: var(--adv-spacing-24) 0 0 0; + --adv-section-padding: var(--adv-spacing-16); - /* Table */ - --adv-table-width: 100%; - --adv-table-margin: 0; - --adv-table-padding: 0; - --adv-table-border: none; - --adv-table-vertical-align: top; - --adv-table-line-height: 16px; - --adv-table-row-border-width: var(--adv-border-width); - --adv-table-row-border-style: var(--adv-border-style); - --adv-table-row-border-color: var(--adv-border-color); - --adv-table-row-border: var(--adv-table-row-border-width) var(--adv-table-row-border-style) var(--adv-table-row-border-color); - --adv-table-row-changed-background-color: var(--adv-color-grey-10); - --adv-table-cell-padding-top: var(--adv-spacing-12); - --adv-table-cell-padding-right: calc(var(--adv-spacing-16) + var(--adv-spacing-24)); - --adv-table-cell-padding-bottom: var(--adv-spacing-12); - --adv-table-cell-padding-left: var(--adv-spacing-16); - --adv-table-cell-padding: var(--adv-table-cell-padding-top) var(--adv-table-cell-padding-right) var(--adv-table-cell-padding-bottom) var(--adv-table-cell-padding-left); - --adv-table-cell-text-align: left; - --adv-table-first-column-padding-left: var(--adv-spacing-24); - --adv-table-condensed-cell-padding-y: var(--adv-spacing-8); - --adv-table-condensed-cell-padding: var(--adv-table-condensed-cell-padding-y) var(--adv-table-cell-padding-right) var(--adv-table-condensed-cell-padding-y) var(--adv-table-cell-padding-left); - --adv-table-condensed-font-size: var(--adv-text-font-size-small); + /* Table */ + --adv-table-width: 100%; + --adv-table-margin: 0; + --adv-table-padding: 0; + --adv-table-border: none; + --adv-table-vertical-align: top; + --adv-table-line-height: 16px; + --adv-table-row-border-width: var(--adv-border-width); + --adv-table-row-border-style: var(--adv-border-style); + --adv-table-row-border-color: var(--adv-border-color); + --adv-table-row-border: var(--adv-table-row-border-width) var(--adv-table-row-border-style) + var(--adv-table-row-border-color); + --adv-table-row-changed-background-color: var(--adv-color-grey-10); + --adv-table-cell-padding-top: var(--adv-spacing-12); + --adv-table-cell-padding-right: calc(var(--adv-spacing-16) + var(--adv-spacing-24)); + --adv-table-cell-padding-bottom: var(--adv-spacing-12); + --adv-table-cell-padding-left: var(--adv-spacing-16); + --adv-table-cell-padding: var(--adv-table-cell-padding-top) var(--adv-table-cell-padding-right) + var(--adv-table-cell-padding-bottom) var(--adv-table-cell-padding-left); + --adv-table-cell-text-align: left; + --adv-table-first-column-padding-left: var(--adv-spacing-24); + --adv-table-condensed-cell-padding-y: var(--adv-spacing-8); + --adv-table-condensed-cell-padding: var(--adv-table-condensed-cell-padding-y) + var(--adv-table-cell-padding-right) var(--adv-table-condensed-cell-padding-y) + var(--adv-table-cell-padding-left); + --adv-table-condensed-font-size: var(--adv-text-font-size-small); } diff --git a/src/types/index.ts b/src/types/index.ts index a9a6192..46958ad 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,31 +1,31 @@ // Enums export enum ElementTypes { - Chapter = 'chapter', - Section = 'section', - Paragraph = 'paragraph', - Text = 'text', - Weblink = 'weblink', - List = 'list', - Table = 'table', - InternalReference = 'internalReference' + Chapter = 'chapter', + Section = 'section', + Paragraph = 'paragraph', + Text = 'text', + Weblink = 'weblink', + List = 'list', + Table = 'table', + InternalReference = 'internalReference', } export enum TextStyle { - Bold = 'BOLD', - Italic = 'ITALIC' + Bold = 'BOLD', + Italic = 'ITALIC', } // Interfaces export interface ContentElements { - contentElements: Element[]; + contentElements: Element[]; } export interface Element extends ContentElements { - type: ElementTypes; + type: ElementTypes; } export interface TopLevelElement { - isTopLevel?: boolean; + isTopLevel?: boolean; } // Elements @@ -39,7 +39,13 @@ type ListStyle = { ordered: boolean }; type ListItem = { content: Element[]; subList: List }; type TableCell = { elements: Element[] }; type TableRow = TableCell[]; -type Table = { rows: TableRow[]; label: string; captions: Element[]; titlePrefix: Text; title: Text }; +type Table = { + rows: TableRow[]; + label: string; + captions: Element[]; + titlePrefix: Text; + title: Text; +}; type InternalReference = { referencedLabel: string; displayText: Text }; type DocumentViewerAnalytics = { onExpandSection?: (title: string) => void }; diff --git a/src/utils/id-generator.ts b/src/utils/id-generator.ts index 0dd0a23..9aae317 100644 --- a/src/utils/id-generator.ts +++ b/src/utils/id-generator.ts @@ -1,6 +1,6 @@ let idCounter = Date.now(); export const getUniqueId = (prefix = 'id') => { - idCounter += 1; - return `${prefix}-${idCounter}`; + idCounter += 1; + return `${prefix}-${idCounter}`; }; diff --git a/src/utils/scroll.ts b/src/utils/scroll.ts index 28aeac8..1661499 100644 --- a/src/utils/scroll.ts +++ b/src/utils/scroll.ts @@ -1,13 +1,13 @@ export const getScrollParent = (node) => { - const isElement = node instanceof HTMLElement; - const overflowY = isElement && window.getComputedStyle(node).overflowY; - const isScrollable = overflowY !== 'visible' && overflowY !== 'hidden'; + const isElement = node instanceof HTMLElement; + const overflowY = isElement && window.getComputedStyle(node).overflowY; + const isScrollable = overflowY !== 'visible' && overflowY !== 'hidden'; - if (!node) { - return -1; - } else if (isScrollable) { - return node; - } + if (!node) { + return -1; + } else if (isScrollable) { + return node; + } - return getScrollParent(node.parentNode) || document.body; + return getScrollParent(node.parentNode) || document.body; }; diff --git a/tsconfig.json b/tsconfig.json index 2eb4786..22d4f35 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,20 +1,20 @@ { - "compilerOptions": { - "allowJs": true, - "checkJs": false, - "outDir": "dist", - "moduleResolution": "node", - "module": "commonjs", - "target": "es5", - "jsx": "react", - "jsxFactory": "h", - "declaration": true, - "resolveJsonModule": true, - "esModuleInterop": true, - "sourceMap": false, - "baseUrl": "./", - "lib": ["ES2021"] - }, - "include": ["src/"], - "exclude": ["node_modules"] + "compilerOptions": { + "allowJs": true, + "checkJs": false, + "outDir": "dist", + "moduleResolution": "node", + "module": "commonjs", + "target": "es5", + "jsx": "react", + "jsxFactory": "h", + "declaration": true, + "resolveJsonModule": true, + "esModuleInterop": true, + "sourceMap": false, + "baseUrl": "./", + "lib": ["ES2021"] + }, + "include": ["src/"], + "exclude": ["node_modules"] } diff --git a/webpack.common.js b/webpack.common.js index a9d943b..7502d17 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -3,40 +3,40 @@ const isProd = process.env.NODE_ENV === 'production'; const autoprefixer = require('autoprefixer'); module.exports = { - module: { - rules: [ - { - test: /\.(ts|tsx)$/, - use: 'ts-loader', - exclude: /node_modules/ - }, - { - test: /\.js$/, - exclude: /node_modules/, - use: { - loader: 'babel-loader', - options: { - presets: ['@babel/preset-env'], - cacheCompression: false, - cacheDirectory: true, - plugins: [!isProd && '@prefresh/babel-plugin'].filter(Boolean) - } - } - }, - { - test: /\.scss$/, - use: [ - isProd ? MiniCssExtractPlugin.loader : 'style-loader', - { loader: 'css-loader', options: { importLoaders: 1 } }, - { loader: 'sass-loader', options: { implementation: require('sass') } } - ].filter(Boolean) - }, - { - test: /\.css$/, - use: 'css-loader' - } - ] - }, - resolve: { extensions: ['.tsx', '.ts', '.js', '.json'] }, - plugins: [autoprefixer] + module: { + rules: [ + { + test: /\.(ts|tsx)$/, + use: 'ts-loader', + exclude: /node_modules/, + }, + { + test: /\.js$/, + exclude: /node_modules/, + use: { + loader: 'babel-loader', + options: { + presets: ['@babel/preset-env'], + cacheCompression: false, + cacheDirectory: true, + plugins: [!isProd && '@prefresh/babel-plugin'].filter(Boolean), + }, + }, + }, + { + test: /\.scss$/, + use: [ + isProd ? MiniCssExtractPlugin.loader : 'style-loader', + { loader: 'css-loader', options: { importLoaders: 1 } }, + { loader: 'sass-loader', options: { implementation: require('sass') } }, + ].filter(Boolean), + }, + { + test: /\.css$/, + use: 'css-loader', + }, + ], + }, + resolve: { extensions: ['.tsx', '.ts', '.js', '.json'] }, + plugins: [autoprefixer], }; diff --git a/webpack.dev.js b/webpack.dev.js index 3bcea66..45fb8b9 100644 --- a/webpack.dev.js +++ b/webpack.dev.js @@ -7,20 +7,20 @@ const PreactRefreshWebpackPlugin = require('@prefresh/webpack'); const common = require('./webpack.common'); module.exports = merge(common, { - mode: 'development', - entry: './playground/example.js', - watchOptions: { ignored: /node_modules/, aggregateTimeout: 300, poll: 300 }, - plugins: [ - new ESLintPlugin({ extensions: ['ts', 'tsx', 'js'] }), - new PreactRefreshWebpackPlugin(), - new StylelintPlugin(), - new HTMLWebpackPlugin({ template: './playground/index.html', inject: 'body' }) - ], - devtool: 'inline-source-map', - devServer: { - hot: true, - host: '0.0.0.0', - static: path.join(__dirname, 'dist'), - client: { logging: 'warn', overlay: false } - } + mode: 'development', + entry: './playground/example.js', + watchOptions: { ignored: /node_modules/, aggregateTimeout: 300, poll: 300 }, + plugins: [ + new ESLintPlugin({ extensions: ['ts', 'tsx', 'js'] }), + new PreactRefreshWebpackPlugin(), + new StylelintPlugin(), + new HTMLWebpackPlugin({ template: './playground/index.html', inject: 'body' }), + ], + devtool: 'inline-source-map', + devServer: { + hot: true, + host: '0.0.0.0', + static: path.join(__dirname, 'dist'), + client: { logging: 'warn', overlay: false }, + }, }); diff --git a/webpack.prod.js b/webpack.prod.js index 438710c..f245182 100644 --- a/webpack.prod.js +++ b/webpack.prod.js @@ -6,27 +6,27 @@ const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); module.exports = merge(common, { - mode: 'production', - devtool: false, - entry: './src/index.tsx', - output: { - filename: 'adyen-document-viewer.min.js', - library: { name: 'AdyenDocumentViewer', type: 'umd', export: 'default' } - }, - optimization: { - minimizer: [ - new TerserPlugin({ - extractComments: false, - terserOptions: { format: { comments: false } } - }), - new CssMinimizerPlugin() - ] - }, - plugins: [ - new LoaderOptionsPlugin({ minimize: true }), - new MiniCssExtractPlugin({ - filename: 'adyen-document-viewer.min.css', - ignoreOrder: true - }) - ] + mode: 'production', + devtool: false, + entry: './src/index.tsx', + output: { + filename: 'adyen-document-viewer.min.js', + library: { name: 'AdyenDocumentViewer', type: 'umd', export: 'default' }, + }, + optimization: { + minimizer: [ + new TerserPlugin({ + extractComments: false, + terserOptions: { format: { comments: false } }, + }), + new CssMinimizerPlugin(), + ], + }, + plugins: [ + new LoaderOptionsPlugin({ minimize: true }), + new MiniCssExtractPlugin({ + filename: 'adyen-document-viewer.min.css', + ignoreOrder: true, + }), + ], }); From 7c5f05c6f67a16fbfa99add0ceb7dd6fa2d18b42 Mon Sep 17 00:00:00 2001 From: georgei Date: Fri, 23 Feb 2024 15:57:00 +0100 Subject: [PATCH 05/16] Add .git-blame-ignore-revs file --- .git-blame-ignore-revs | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .git-blame-ignore-revs diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 0000000..d974747 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,2 @@ +# Change tab width to 2 +65c4ba06306fe0b1dedab4a8ae11e769305727c9 \ No newline at end of file From c821b0bb414dc76c27cdd63d05f698254dfcb542 Mon Sep 17 00:00:00 2001 From: georgei Date: Mon, 26 Feb 2024 13:44:30 +0100 Subject: [PATCH 06/16] Update dependencies --- .eslintrc.js | 5 +---- package.json | 61 ++++++++++++++++++++++++++-------------------------- 2 files changed, 31 insertions(+), 35 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index c60849a..99b01ba 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,6 +1,6 @@ module.exports = { parser: '@typescript-eslint/parser', - plugins: ['react', '@typescript-eslint', 'import', 'eslint-plugin-tsdoc', 'jsx-a11y'], + plugins: ['react', '@typescript-eslint', 'import', 'jsx-a11y'], extends: [ 'eslint:recommended', 'plugin:react/recommended', @@ -101,9 +101,6 @@ module.exports = { 'react/prop-types': 'off', 'react/display-name': 'off', - // TSDoc - 'tsdoc/syntax': 'warn', - // a11y 'jsx-a11y/alt-text': 'error', 'jsx-a11y/aria-role': 'error', diff --git a/package.json b/package.json index 4d2104c..c3c2235 100644 --- a/package.json +++ b/package.json @@ -19,45 +19,44 @@ "lint:fix": "npm run lint -- --fix" }, "devDependencies": { - "@babel/core": "^7.17.8", - "@babel/preset-env": "^7.16.11", - "@prefresh/babel-plugin": "^0.4.3", - "@prefresh/webpack": "^3.3.3", - "@typescript-eslint/eslint-plugin": "^5.4.0", - "@typescript-eslint/parser": "^5.8.1", - "autoprefixer": "^9.8.8", - "babel-loader": "^8.2.3", + "@babel/core": "^7.23.9", + "@babel/preset-env": "^7.23.9", + "@prefresh/babel-plugin": "^0.5.0", + "@prefresh/webpack": "^4.0.0", + "@typescript-eslint/eslint-plugin": "^6.19.1", + "@typescript-eslint/parser": "^6.19.1", + "autoprefixer": "^10.4.17", + "babel-loader": "^9.1.3", "cross-env": "^7.0.3", - "css-loader": "^4.3.0", - "css-minimizer-webpack-plugin": "^3.2.0", + "css-loader": "^6.10.0", + "css-minimizer-webpack-plugin": "^5.0.1", "eslint": "^8.12.0", - "eslint-import-resolver-typescript": "^2.5.0", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-react": "^7.26.1", - "eslint-plugin-tsdoc": "^0.2.14", - "eslint-webpack-plugin": "^3.1.1", - "html-webpack-plugin": "^5.5.0", - "mini-css-extract-plugin": "^2.4.5", - "prettier": "2.7.1", - "sass": "^1.43.4", - "sass-loader": "^12.3.0", - "style-loader": "^3.3.1", + "eslint-import-resolver-typescript": "^3.6.1", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-jsx-a11y": "^6.8.0", + "eslint-plugin-react": "^7.33.2", + "eslint-webpack-plugin": "^4.0.1", + "html-webpack-plugin": "^5.6.0", + "mini-css-extract-plugin": "^2.7.7", + "prettier": "3.2.4", + "sass": "^1.70.0", + "sass-loader": "^13.2.2", + "style-loader": "^3.3.4", "stylelint": "^14.1.0", "stylelint-config-recommended": "^6.0.0", "stylelint-config-sass-guidelines": "^9.0.1", "stylelint-scss": "^4.2.0", "stylelint-webpack-plugin": "^3.1.0", - "terser-webpack-plugin": "^5.2.4", - "ts-loader": "^9.2.6", - "typescript": "^4.4.4", - "webpack": "^5.61.0", - "webpack-cli": "^4.9.1", - "webpack-dev-server": "^4.4.0", + "terser-webpack-plugin": "^5.3.10", + "ts-loader": "^9.5.1", + "typescript": "^5.3.3", + "webpack": "^5.90.0", + "webpack-cli": "^5.0.0", + "webpack-dev-server": "^4.15.1", "webpack-merge": "^5.8.0", - "classnames": "^2.3.1", - "core-js": "^3.20.2", - "preact": "^10.5.15" + "classnames": "^2.5.1", + "core-js": "^3.35.1", + "preact": "^10.19.3" }, "license": "SEE LICENSE IN LICENSE", "repository": { From bbaad24cdbbedbb445c2aa93b057a0b553b39ea5 Mon Sep 17 00:00:00 2001 From: georgei Date: Wed, 6 Mar 2024 10:54:36 +0100 Subject: [PATCH 07/16] Fix internal references to collapsed sections --- playground/example.json | 21 ++- src/DocumentViewer.tsx | 23 +-- src/ReferenceContext/ReferenceContext.tsx | 15 ++ .../ReferenceContextProvider.tsx | 27 ++++ src/ReferenceContext/useReferenceContext.ts | 11 ++ src/components/Accordion/types.ts | 1 - .../AccordionItem/AccordionItem.tsx | 15 +- src/components/AccordionItem/types.ts | 2 + .../ContentElements/ContentElements.tsx | 141 +++++++++--------- .../InternalReference/InternalReference.tsx | 15 +- src/components/Section/Section.tsx | 52 ++++++- src/components/Table/Table.tsx | 11 +- src/index.tsx | 4 +- src/types/index.ts | 67 ++++++--- src/utils/delay.ts | 4 + src/utils/format-id.ts | 5 + 16 files changed, 300 insertions(+), 114 deletions(-) create mode 100644 src/ReferenceContext/ReferenceContext.tsx create mode 100644 src/ReferenceContext/ReferenceContextProvider.tsx create mode 100644 src/ReferenceContext/useReferenceContext.ts create mode 100644 src/utils/delay.ts create mode 100644 src/utils/format-id.ts diff --git a/playground/example.json b/playground/example.json index 9bc79e9..72e896b 100644 --- a/playground/example.json +++ b/playground/example.json @@ -46,9 +46,18 @@ }, { "type": "text", - "content": " This is a bold and italic example.", + "content": " This is a bold and italic example. ", "styles": ["BOLD", "ITALIC"] }, + { + "type": "internalReference", + "referencedLabel": "tableReference", + "displayText": { + "type": "text", + "content": "This should take you to the table in the section below.", + "styles": [] + } + }, { "type": "paragraph", "contentElements": [ @@ -102,9 +111,13 @@ { "content": [ { - "type": "text", - "content": "Second Sub item:", - "styles": [] + "type": "internalReference", + "referencedLabel": "2", + "displayText": { + "type": "text", + "content": "Second section", + "styles": [] + } } ], "subList": null diff --git a/src/DocumentViewer.tsx b/src/DocumentViewer.tsx index c5e862d..2782023 100644 --- a/src/DocumentViewer.tsx +++ b/src/DocumentViewer.tsx @@ -5,6 +5,7 @@ import cx from 'classnames'; import Heading from './components/Heading/Heading'; import Text from './components/Text/Text'; import ContentElements from './components/ContentElements/ContentElements'; +import { ReferenceContextProvider } from './ReferenceContext/ReferenceContextProvider'; export default function DocumentViewer({ document, @@ -14,15 +15,17 @@ export default function DocumentViewer({ const classNames = cx('adyen-document-viewer', className); return ( -
    - - - - -
    + +
    + + + + +
    +
    ); } diff --git a/src/ReferenceContext/ReferenceContext.tsx b/src/ReferenceContext/ReferenceContext.tsx new file mode 100644 index 0000000..58a043c --- /dev/null +++ b/src/ReferenceContext/ReferenceContext.tsx @@ -0,0 +1,15 @@ +import { createContext } from 'preact'; + +export interface ReferenceContextValue { + references: References; + addReference: (references: References) => void; +} + +export interface References { + [label: string]: { openSection: () => void }; +} + +export const ReferenceContext = createContext({ + references: {}, + addReference: () => {}, +}); diff --git a/src/ReferenceContext/ReferenceContextProvider.tsx b/src/ReferenceContext/ReferenceContextProvider.tsx new file mode 100644 index 0000000..8c73c66 --- /dev/null +++ b/src/ReferenceContext/ReferenceContextProvider.tsx @@ -0,0 +1,27 @@ +import { ComponentChildren, h } from 'preact'; +import { useMemo, useState } from 'preact/hooks'; + +import { ReferenceContext, ReferenceContextValue, References } from './ReferenceContext'; + +interface ReferenceProps { + children?: ComponentChildren; +} + +export function ReferenceContextProvider({ children }: ReferenceProps) { + const [references, setReferences] = useState({}); + + const contextValue: ReferenceContextValue = useMemo( + () => ({ + addReference: (reference: References) => { + setReferences((prevReferences) => ({ + ...prevReferences, + ...reference, + })); + }, + references, + }), + [references, setReferences], + ); + + return {children}; +} diff --git a/src/ReferenceContext/useReferenceContext.ts b/src/ReferenceContext/useReferenceContext.ts new file mode 100644 index 0000000..fa666cb --- /dev/null +++ b/src/ReferenceContext/useReferenceContext.ts @@ -0,0 +1,11 @@ +import { useContext } from 'preact/hooks'; + +import { ReferenceContext } from './ReferenceContext'; + +export function useReferenceContext() { + const context = useContext(ReferenceContext); + if (context === undefined) { + throw new Error('useReferenceContext must be used within a ReferenceProvider'); + } + return context; +} diff --git a/src/components/Accordion/types.ts b/src/components/Accordion/types.ts index bf54447..22e8e6f 100644 --- a/src/components/Accordion/types.ts +++ b/src/components/Accordion/types.ts @@ -1,5 +1,4 @@ import { ComponentChildren } from 'preact'; -import AccordionItem from '../AccordionItem/AccordionItem'; export interface AccordionProps { children: ComponentChildren; diff --git a/src/components/AccordionItem/AccordionItem.tsx b/src/components/AccordionItem/AccordionItem.tsx index c64ac17..ee6eda8 100644 --- a/src/components/AccordionItem/AccordionItem.tsx +++ b/src/components/AccordionItem/AccordionItem.tsx @@ -8,7 +8,13 @@ import { useState, useEffect } from 'preact/hooks'; import { AccordionItemState } from '../Accordion/types'; import './AccordionItem.scss'; -export default function AccordionItem({ children, open = false, title = '' }: AccordionItemProps) { +export default function AccordionItem({ + children, + open = false, + title = '', + onOpen = () => {}, + onClose = () => {}, +}: AccordionItemProps) { const { expand, items, setItems, onExpandSection } = useAccordionContext(); const [isOpen, setIsOpen] = useState(open); @@ -38,7 +44,12 @@ export default function AccordionItem({ children, open = false, title = '' }: Ac }, [items]); useEffect(() => { - isOpen && onExpandSection?.(title); + if (isOpen) { + onExpandSection?.(title); + onOpen(); + } else { + onClose(); + } }, [isOpen]); return ( diff --git a/src/components/AccordionItem/types.ts b/src/components/AccordionItem/types.ts index 8de46ec..c82baf2 100644 --- a/src/components/AccordionItem/types.ts +++ b/src/components/AccordionItem/types.ts @@ -4,4 +4,6 @@ export interface AccordionItemProps { children: ComponentChildren; open?: boolean; title?: string; + onOpen?: () => void; + onClose?: () => void; } diff --git a/src/components/ContentElements/ContentElements.tsx b/src/components/ContentElements/ContentElements.tsx index 9da6506..f4ab9f9 100644 --- a/src/components/ContentElements/ContentElements.tsx +++ b/src/components/ContentElements/ContentElements.tsx @@ -1,5 +1,5 @@ import { h, VNode } from 'preact'; -import { ContentElementsProps, ElementTypes } from '../../types'; +import { Element, ContentElementsProps, ElementTypes } from '../../types'; import { getUniqueId } from '../../utils/id-generator'; import Accordion from '../Accordion/Accordion'; import Chapter from '../Chapter/Chapter'; @@ -11,80 +11,85 @@ import List from '../ListElemennt/List'; import Table from '../Table/Table'; import InternalReference from '../InternalReference/InternalReference'; +const components = { + chapter: Chapter, + section: Section, + paragraph: Paragraph, + text: Text, + weblink: Weblink, + list: List, + table: Table, + internalReference: InternalReference, + breakline: 'br', +}; + +const getKey = (type: ElementTypes) => `key-${type}-${getUniqueId()}`; + +const getProps = (element: Element, isTopLevel: boolean): any => { + if (!('type' in element)) return null; + + switch (element.type) { + case ElementTypes.Chapter: + return { + title: element.title, + contentElements: element.contentElements, + }; + case ElementTypes.Section: + return { + isTopLevel, + title: element.title, + label: element.label, + contentElements: element.contentElements, + }; + case ElementTypes.Paragraph: + return { + isTopLevel, + contentElements: element.contentElements, + }; + case ElementTypes.Text: + return { + content: element.content, + styles: element.styles, + }; + case ElementTypes.Weblink: + return { + url: element.url, + displayText: element.displayText, + }; + case ElementTypes.List: + return { + items: element.items, + style: element.style, + }; + case ElementTypes.Table: + return { + rows: element.rows, + label: element.label, + captions: element.captions, + titlePrefix: element.titlePrefix, + title: element.title, + }; + case ElementTypes.InternalReference: + return { + referencedLabel: element.referencedLabel, + displayText: element.displayText, + }; + default: + return null; + } +}; export default function ContentElements({ contentElements, isTopLevel = false, onExpandSection, }: ContentElementsProps) { - const components = { - chapter: Chapter, - section: Section, - paragraph: Paragraph, - text: Text, - weblink: Weblink, - list: List, - table: Table, - internalReference: InternalReference, - breakline: 'br', - }; - - const getKey = (type: string) => `key-${type}-${getUniqueId()}`; - - const getProps = (element): any => { - switch (element.type) { - case ElementTypes.Chapter: - return { - title: element.title, - contentElements: element.contentElements, - }; - case ElementTypes.Section: - return { - isTopLevel, - title: element.title, - label: element.label, - contentElements: element.contentElements, - }; - case ElementTypes.Paragraph: - return { - isTopLevel, - contentElements: element.contentElements, - }; - case ElementTypes.Text: - return { - content: element.content, - styles: element.styles, - }; - case ElementTypes.Weblink: - return { - url: element.url, - displayText: element.displayText, - }; - case ElementTypes.List: - return { - items: element.items, - style: element.style, - }; - case ElementTypes.Table: - return { - rows: element.rows, - label: element.label, - captions: element.captions, - titlePrefix: element.titlePrefix, - title: element.title, - }; - case ElementTypes.InternalReference: - return { - referencedLabel: element.referencedLabel, - displayText: element.displayText, - }; - default: - return null; - } - }; + const elements = contentElements.map((contentElement): VNode | null => { + if (!('type' in contentElement)) return null; - const elements = contentElements.map((contentElement): VNode => { const Component = components[contentElement.type]; - return ; + return ( + + ); }); return isTopLevel ? ( diff --git a/src/components/InternalReference/InternalReference.tsx b/src/components/InternalReference/InternalReference.tsx index 636a5cb..07e935b 100644 --- a/src/components/InternalReference/InternalReference.tsx +++ b/src/components/InternalReference/InternalReference.tsx @@ -2,14 +2,23 @@ import { h } from 'preact'; import { InternalReferenceProps } from '../../types'; import LinkButton from '../LinkButton/LinkButton'; import { getScrollParent } from '../../utils/scroll'; +import { formatId } from '../../utils/format-id'; +import { useReferenceContext } from '../../ReferenceContext/useReferenceContext'; +import { delay } from '../../utils/delay'; export default function InternalReference({ - referencedLabel, + referencedLabel: originalReferencedLabel, displayText, }: InternalReferenceProps) { + const referencedLabel = formatId(originalReferencedLabel) ?? ''; const label = displayText ? displayText.content : referencedLabel; - - const scrollIntoView = () => { + const { references } = useReferenceContext(); + const scrollIntoView = async () => { + if (references && referencedLabel && references[referencedLabel]) { + references[referencedLabel].openSection(); + // leave some time for the accordion item to expand + await delay(150); + } const scrollParent = getScrollParent(document.getElementById(referencedLabel)); const element = scrollParent !== -1 && scrollParent.querySelector('#' + referencedLabel); element?.scrollIntoView({ behavior: 'smooth' }); diff --git a/src/components/Section/Section.tsx b/src/components/Section/Section.tsx index cd447e3..2333dd6 100644 --- a/src/components/Section/Section.tsx +++ b/src/components/Section/Section.tsx @@ -5,10 +5,58 @@ import Text from '../Text/Text'; import './Section.scss'; import AccordionItem from '../AccordionItem/AccordionItem'; import ContentElements from '../ContentElements/ContentElements'; +import { useEffect, useState } from 'preact/hooks'; +import { useReferenceContext } from '../../ReferenceContext/useReferenceContext'; +import { formatId } from '../../utils/format-id'; + +const extractLabels = (obj) => { + if (typeof obj !== 'object' || obj === null) { + return []; + } + + if ('label' in obj) { + return [obj.label]; + } + + return Object.values(obj).flatMap((value) => extractLabels(value)); +}; + +export default function Section({ + title, + label: originalLabel, + isTopLevel, + contentElements, +}: SectionProps) { + const [isOpen, setIsOpen] = useState(false); + const { addReference } = useReferenceContext(); + + const label = formatId(originalLabel); + + useEffect(() => { + if (isTopLevel) { + const references = extractLabels(contentElements).map(formatId); + if (label) { + references.push(label); + } + if (references.length) { + references.forEach((reference) => { + addReference({ [reference as string]: { openSection: () => setIsOpen(true) } }); + }); + } + } + }, []); -export default function Section({ title, label, isTopLevel, contentElements }: SectionProps) { return isTopLevel ? ( - + { + setIsOpen(true); + }} + onClose={() => { + setIsOpen(false); + }} + >
    diff --git a/src/components/Table/Table.tsx b/src/components/Table/Table.tsx index 71b7a02..76bb954 100644 --- a/src/components/Table/Table.tsx +++ b/src/components/Table/Table.tsx @@ -3,8 +3,17 @@ import { TableProps } from '../../types'; import Text from '../Text/Text'; import ContentElements from '../ContentElements/ContentElements'; import './Table.scss'; +import { formatId } from '../../utils/format-id'; + +export default function Table({ + rows, + label: originalLabel, + captions, + titlePrefix, + title, +}: TableProps) { + const label = formatId(originalLabel); -export default function Table({ rows, label, captions, titlePrefix, title }: TableProps) { return (
    diff --git a/src/index.tsx b/src/index.tsx index 4419e80..078cbf4 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,3 +1,5 @@ +import { Document } from './types'; + if (process.env.NODE_ENV === 'development') { require('preact/debug'); } @@ -28,7 +30,7 @@ export default class AdyenDocumentViewer { * Renders the document * @param document - The JSON document */ - render(document: JSON): void { + render(document: Document): void { render(, this.target); } } diff --git a/src/types/index.ts b/src/types/index.ts index 46958ad..378d392 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -16,47 +16,70 @@ export enum TextStyle { } // Interfaces -export interface ContentElements { +export interface ElementWithInnerContent { contentElements: Element[]; } -export interface Element extends ContentElements { - type: ElementTypes; -} - export interface TopLevelElement { isTopLevel?: boolean; } // Elements -type Chapter = ContentElements & { title: Text }; -type Section = ContentElements & { title: Text; label: string }; -type Paragraph = ContentElements; -type Text = { content: string; styles?: TextStyle[] }; -type Weblink = { url: string; displayText: Text }; -type List = { style: ListStyle; items: ListItem[] }; +export type Document = ElementWithInnerContent & { title: Text }; +type Chapter = ElementWithInnerContent & { type: ElementTypes.Chapter; title: Text }; +type Section = ElementWithInnerContent & { type: ElementTypes.Section; title: Text; label: string }; +type Paragraph = ElementWithInnerContent & { type: ElementTypes.Paragraph }; +type Text = { type: ElementTypes.Text; content: string; styles?: TextStyle[] }; +type Weblink = { type: ElementTypes.Weblink; url: string; displayText: Text }; +type List = { type: ElementTypes.List; style: ListStyle; items: ListItem[] }; type ListStyle = { ordered: boolean }; type ListItem = { content: Element[]; subList: List }; type TableCell = { elements: Element[] }; type TableRow = TableCell[]; type Table = { + type: ElementTypes.Table; rows: TableRow[]; label: string; captions: Element[]; titlePrefix: Text; title: Text; }; -type InternalReference = { referencedLabel: string; displayText: Text }; +type InternalReference = { + type: ElementTypes.InternalReference; + referencedLabel: string; + displayText: Text; +}; type DocumentViewerAnalytics = { onExpandSection?: (title: string) => void }; +export type Element = + | Document + | Chapter + | Section + | Paragraph + | Text + | Weblink + | List + | ListStyle + | ListItem + | TableCell + | TableRow + | Table + | InternalReference + | DocumentViewerAnalytics; + // Props -export type DocumentViewerProps = { document: any; className?: string } & DocumentViewerAnalytics; -export type ContentElementsProps = ContentElements & TopLevelElement & DocumentViewerAnalytics; -export type ChapterProps = Chapter; -export type SectionProps = Section & TopLevelElement; -export type ParagraphProps = Paragraph & TopLevelElement; -export type TextProps = Text; -export type WeblinkProps = Weblink; -export type ListProps = List; -export type TableProps = Table; -export type InternalReferenceProps = InternalReference; +export type DocumentViewerProps = { + document: Document; + className?: string; +} & DocumentViewerAnalytics; +export type ContentElementsProps = ElementWithInnerContent & + TopLevelElement & + DocumentViewerAnalytics; +export type ChapterProps = Omit; +export type SectionProps = Omit
    ; +export type ParagraphProps = Omit; +export type TextProps = Omit; +export type WeblinkProps = Omit; +export type ListProps = Omit; +export type TableProps = Omit; +export type InternalReferenceProps = Omit; diff --git a/src/utils/delay.ts b/src/utils/delay.ts new file mode 100644 index 0000000..694db84 --- /dev/null +++ b/src/utils/delay.ts @@ -0,0 +1,4 @@ +export const delay = (time: number): Promise => + new Promise((resolve) => { + setTimeout(resolve, time); + }); diff --git a/src/utils/format-id.ts b/src/utils/format-id.ts new file mode 100644 index 0000000..ee28a09 --- /dev/null +++ b/src/utils/format-id.ts @@ -0,0 +1,5 @@ +export const formatId = (id: string) => { + if (!id) return; + const strippedId = id.replace(/[^\w-]/g, ''); + return `adyen-document-viewer-${strippedId}`; +}; From 69b7ca1df9f84c0e72d6d3d626273266ab70f055 Mon Sep 17 00:00:00 2001 From: vergil Date: Tue, 5 Mar 2024 13:50:15 +0100 Subject: [PATCH 08/16] Rebase main onto the branch --- .browserslistrc | 2 -- playground/index.html => index.html | 4 ++- package.json | 38 +++++++------------- playground/example.js | 3 +- playground/{example.json => mock-data.js} | 2 +- src/index.tsx | 6 +--- tsconfig.json | 30 ++++++++-------- vite.config.ts | 33 ++++++++++++++++++ webpack.common.js | 42 ----------------------- webpack.dev.js | 26 -------------- webpack.prod.js | 32 ----------------- 11 files changed, 67 insertions(+), 151 deletions(-) delete mode 100644 .browserslistrc rename playground/index.html => index.html (52%) rename playground/{example.json => mock-data.js} (99%) create mode 100644 vite.config.ts delete mode 100644 webpack.common.js delete mode 100644 webpack.dev.js delete mode 100644 webpack.prod.js diff --git a/.browserslistrc b/.browserslistrc deleted file mode 100644 index 8afc6dc..0000000 --- a/.browserslistrc +++ /dev/null @@ -1,2 +0,0 @@ -last 2 versions -> 1% diff --git a/playground/index.html b/index.html similarity index 52% rename from playground/index.html rename to index.html index b66f851..169f6f1 100644 --- a/playground/index.html +++ b/index.html @@ -1,10 +1,12 @@ - + + Adyen Document Viewer Example
    + diff --git a/package.json b/package.json index c3c2235..f883cf5 100644 --- a/package.json +++ b/package.json @@ -10,53 +10,36 @@ "version": "1.0.0", "description": "Adyen Document Viewer", "main": "./dist/adyen-document-viewer.min.js", + "type": "module", "types": "./dist/index.d.ts", "scripts": { "clean": "rm -rf dist", - "start": "cross-env NODE_ENV=development webpack serve --config=webpack.dev.js", - "build": "npm run clean && cross-env NODE_ENV=production webpack --config=webpack.prod.js", + "dev": "vite", + "build": "vite build", + "preview": "vite preview", "lint": "eslint 'src/**/*.{js,ts,tsx}'", "lint:fix": "npm run lint -- --fix" }, "devDependencies": { - "@babel/core": "^7.23.9", - "@babel/preset-env": "^7.23.9", + "@preact/preset-vite": "^2.8.1", "@prefresh/babel-plugin": "^0.5.0", - "@prefresh/webpack": "^4.0.0", "@typescript-eslint/eslint-plugin": "^6.19.1", "@typescript-eslint/parser": "^6.19.1", - "autoprefixer": "^10.4.17", - "babel-loader": "^9.1.3", - "cross-env": "^7.0.3", - "css-loader": "^6.10.0", - "css-minimizer-webpack-plugin": "^5.0.1", + "classnames": "^2.5.1", "eslint": "^8.12.0", "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-import": "^2.29.1", "eslint-plugin-jsx-a11y": "^6.8.0", "eslint-plugin-react": "^7.33.2", - "eslint-webpack-plugin": "^4.0.1", - "html-webpack-plugin": "^5.6.0", - "mini-css-extract-plugin": "^2.7.7", + "preact": "^10.19.3", "prettier": "3.2.4", "sass": "^1.70.0", - "sass-loader": "^13.2.2", - "style-loader": "^3.3.4", "stylelint": "^14.1.0", "stylelint-config-recommended": "^6.0.0", "stylelint-config-sass-guidelines": "^9.0.1", "stylelint-scss": "^4.2.0", - "stylelint-webpack-plugin": "^3.1.0", - "terser-webpack-plugin": "^5.3.10", - "ts-loader": "^9.5.1", "typescript": "^5.3.3", - "webpack": "^5.90.0", - "webpack-cli": "^5.0.0", - "webpack-dev-server": "^4.15.1", - "webpack-merge": "^5.8.0", - "classnames": "^2.5.1", - "core-js": "^3.35.1", - "preact": "^10.19.3" + "vite": "^4.5.1" }, "license": "SEE LICENSE IN LICENSE", "repository": { @@ -69,5 +52,8 @@ "dist/index.d.ts", "LICENSE", "README" - ] + ], + "optionalDependencies": { + "@rollup/rollup-darwin-x64": "^4.9.1" + } } diff --git a/playground/example.js b/playground/example.js index c1f405e..b57fcfc 100644 --- a/playground/example.js +++ b/playground/example.js @@ -1,5 +1,6 @@ +import 'preact/debug'; import AdyenDocumentViewer from '../src/index'; -import exampleDocument from './example.json'; +import exampleDocument from './mock-data'; const documentViewer = new AdyenDocumentViewer('#document-viewer'); documentViewer.render(exampleDocument); diff --git a/playground/example.json b/playground/mock-data.js similarity index 99% rename from playground/example.json rename to playground/mock-data.js index 72e896b..6fca6e5 100644 --- a/playground/example.json +++ b/playground/mock-data.js @@ -1,4 +1,4 @@ -{ +export default { "title": { "type": "text", "content": "Example document", diff --git a/src/index.tsx b/src/index.tsx index 078cbf4..84a0442 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,9 +1,5 @@ -import { Document } from './types'; - -if (process.env.NODE_ENV === 'development') { - require('preact/debug'); -} import { h, render } from 'preact'; +import { Document } from './types'; import DocumentViewer from './DocumentViewer'; export default class AdyenDocumentViewer { diff --git a/tsconfig.json b/tsconfig.json index 22d4f35..5155153 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,20 +1,20 @@ { "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "noEmit": true, "allowJs": true, - "checkJs": false, - "outDir": "dist", - "moduleResolution": "node", - "module": "commonjs", - "target": "es5", - "jsx": "react", - "jsxFactory": "h", - "declaration": true, - "resolveJsonModule": true, - "esModuleInterop": true, - "sourceMap": false, - "baseUrl": "./", - "lib": ["ES2021"] + "checkJs": true, + + /* Preact Config */ + "jsx": "react-jsx", + "jsxImportSource": "preact", + "skipLibCheck": true, + "paths": { + "react": ["./node_modules/preact/compat/"], + "react-dom": ["./node_modules/preact/compat/"], + }, }, - "include": ["src/"], - "exclude": ["node_modules"] + "include": ["node_modules/vite/client.d.ts", "src/**/*"], } diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..b404ce5 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,33 @@ +import dns from 'node:dns'; +import { resolve } from 'node:path'; +import { defineConfig } from 'vite'; +import preact from '@preact/preset-vite'; + +// This forces Vite to use `localhost` instead of `127.0.0.1`. Otherwise, we run into CORS issues +// since `localhost:8080` and `localhost:8082` are same-origin, but `127.0.0.1:8082` isn't. +dns.setDefaultResultOrder('verbatim'); + +// https://vitejs.dev/config/ +export default defineConfig(() => { + return { + css: { + modules: { + // Remove this after changing all of our SCSS @import to @use + scopeBehaviour: 'local', + generateScopedName: (name) => name, + }, + }, + build: { + lib: { + name: 'AdyenDocumentViewer', + entry: resolve(__dirname, 'src/index.tsx'), + formats: ['es'], + fileName: 'adyen-document-viewer.min.js', + }, + minify: true, + outDir: resolve(__dirname, 'dist'), + emptyOutDir: true, + }, + plugins: [preact()], + }; +}); diff --git a/webpack.common.js b/webpack.common.js deleted file mode 100644 index 7502d17..0000000 --- a/webpack.common.js +++ /dev/null @@ -1,42 +0,0 @@ -const MiniCssExtractPlugin = require('mini-css-extract-plugin'); -const isProd = process.env.NODE_ENV === 'production'; -const autoprefixer = require('autoprefixer'); - -module.exports = { - module: { - rules: [ - { - test: /\.(ts|tsx)$/, - use: 'ts-loader', - exclude: /node_modules/, - }, - { - test: /\.js$/, - exclude: /node_modules/, - use: { - loader: 'babel-loader', - options: { - presets: ['@babel/preset-env'], - cacheCompression: false, - cacheDirectory: true, - plugins: [!isProd && '@prefresh/babel-plugin'].filter(Boolean), - }, - }, - }, - { - test: /\.scss$/, - use: [ - isProd ? MiniCssExtractPlugin.loader : 'style-loader', - { loader: 'css-loader', options: { importLoaders: 1 } }, - { loader: 'sass-loader', options: { implementation: require('sass') } }, - ].filter(Boolean), - }, - { - test: /\.css$/, - use: 'css-loader', - }, - ], - }, - resolve: { extensions: ['.tsx', '.ts', '.js', '.json'] }, - plugins: [autoprefixer], -}; diff --git a/webpack.dev.js b/webpack.dev.js deleted file mode 100644 index 45fb8b9..0000000 --- a/webpack.dev.js +++ /dev/null @@ -1,26 +0,0 @@ -const { merge } = require('webpack-merge'); -const path = require('path'); -const ESLintPlugin = require('eslint-webpack-plugin'); -const StylelintPlugin = require('stylelint-webpack-plugin'); -const HTMLWebpackPlugin = require('html-webpack-plugin'); -const PreactRefreshWebpackPlugin = require('@prefresh/webpack'); -const common = require('./webpack.common'); - -module.exports = merge(common, { - mode: 'development', - entry: './playground/example.js', - watchOptions: { ignored: /node_modules/, aggregateTimeout: 300, poll: 300 }, - plugins: [ - new ESLintPlugin({ extensions: ['ts', 'tsx', 'js'] }), - new PreactRefreshWebpackPlugin(), - new StylelintPlugin(), - new HTMLWebpackPlugin({ template: './playground/index.html', inject: 'body' }), - ], - devtool: 'inline-source-map', - devServer: { - hot: true, - host: '0.0.0.0', - static: path.join(__dirname, 'dist'), - client: { logging: 'warn', overlay: false }, - }, -}); diff --git a/webpack.prod.js b/webpack.prod.js deleted file mode 100644 index f245182..0000000 --- a/webpack.prod.js +++ /dev/null @@ -1,32 +0,0 @@ -const { LoaderOptionsPlugin } = require('webpack'); -const { merge } = require('webpack-merge'); -const common = require('./webpack.common'); -const TerserPlugin = require('terser-webpack-plugin'); -const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); -const MiniCssExtractPlugin = require('mini-css-extract-plugin'); - -module.exports = merge(common, { - mode: 'production', - devtool: false, - entry: './src/index.tsx', - output: { - filename: 'adyen-document-viewer.min.js', - library: { name: 'AdyenDocumentViewer', type: 'umd', export: 'default' }, - }, - optimization: { - minimizer: [ - new TerserPlugin({ - extractComments: false, - terserOptions: { format: { comments: false } }, - }), - new CssMinimizerPlugin(), - ], - }, - plugins: [ - new LoaderOptionsPlugin({ minimize: true }), - new MiniCssExtractPlugin({ - filename: 'adyen-document-viewer.min.css', - ignoreOrder: true, - }), - ], -}); From 3014382470c3253786d0c34f8af386798c7e0138 Mon Sep 17 00:00:00 2001 From: vergil Date: Wed, 6 Mar 2024 11:30:06 +0100 Subject: [PATCH 09/16] Added a UMD build --- package.json | 1 + vite.config.ts | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index f883cf5..cddbf0d 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ }, "files": [ "dist/adyen-document-viewer.min.js", + "dist/adyen-document-viewer.min.umd.cjs", "dist/adyen-document-viewer.min.css", "dist/index.d.ts", "LICENSE", diff --git a/vite.config.ts b/vite.config.ts index b404ce5..2e8e007 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -11,6 +11,7 @@ dns.setDefaultResultOrder('verbatim'); export default defineConfig(() => { return { css: { + modules: { // Remove this after changing all of our SCSS @import to @use scopeBehaviour: 'local', @@ -21,8 +22,13 @@ export default defineConfig(() => { lib: { name: 'AdyenDocumentViewer', entry: resolve(__dirname, 'src/index.tsx'), - formats: ['es'], - fileName: 'adyen-document-viewer.min.js', + formats: ['es', 'umd'], + fileName: 'adyen-document-viewer.min', + }, + rollupOptions: { + output: { + assetFileNames: "adyen-document-viewer.[ext]", + }, }, minify: true, outDir: resolve(__dirname, 'dist'), From 4fb16a01a14ef4de1146b27fac9849cf6e31fab4 Mon Sep 17 00:00:00 2001 From: vergil Date: Wed, 6 Mar 2024 11:39:04 +0100 Subject: [PATCH 10/16] Export ESM by default, fallback to CJS, build and export types --- package.json | 15 +++++++++++++-- src/scss.d.ts | 1 + tsconfig-build.json | 10 ++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 src/scss.d.ts create mode 100644 tsconfig-build.json diff --git a/package.json b/package.json index cddbf0d..9087c81 100644 --- a/package.json +++ b/package.json @@ -15,10 +15,13 @@ "scripts": { "clean": "rm -rf dist", "dev": "vite", - "build": "vite build", + "build": "vite build && npm run types:build", "preview": "vite preview", "lint": "eslint 'src/**/*.{js,ts,tsx}'", - "lint:fix": "npm run lint -- --fix" + "lint:fix": "npm run lint -- --fix", + "types:build": "tsc --project tsconfig-build.json", + "types:check": "tsc && tsc-strict", + "types:watch": "tsc --watch --preserveWatchOutput" }, "devDependencies": { "@preact/preset-vite": "^2.8.1", @@ -54,6 +57,14 @@ "LICENSE", "README" ], + "exports": { + "./adyen-document-viewer.min.js": { + "types": "./dist/index.d.ts", + "import": "./dist/adyen-document-viewer.min.js", + "require": "./dist/adyen-document-viewer.min.umd.cjs" + }, + "./adyen-document-viewer.min.css": "./dist/adyen-document-viewer.min.css" + }, "optionalDependencies": { "@rollup/rollup-darwin-x64": "^4.9.1" } diff --git a/src/scss.d.ts b/src/scss.d.ts new file mode 100644 index 0000000..caaba6a --- /dev/null +++ b/src/scss.d.ts @@ -0,0 +1 @@ +declare module '*.scss'; \ No newline at end of file diff --git a/tsconfig-build.json b/tsconfig-build.json new file mode 100644 index 0000000..b1a0199 --- /dev/null +++ b/tsconfig-build.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "include": [], + "files": ["src/index.tsx", "node_modules/vite/client.d.ts", "src/scss.d.ts"], + "compilerOptions": { + "rootDir": "src", + "noEmit": false, + "emitDeclarationOnly": true + } +} \ No newline at end of file From b6f19fe2e0cec191315409853d5ca7e241e90ccc Mon Sep 17 00:00:00 2001 From: georgei Date: Thu, 7 Mar 2024 13:58:38 +0100 Subject: [PATCH 11/16] Tweak tsconfig to maintain backwards compatibility --- .eslintrc.js => .eslintrc.cjs | 0 package.json | 13 +++++++------ tsconfig-build.json | 4 +++- tsconfig.json | 1 + vite.config.ts | 9 ++++----- 5 files changed, 15 insertions(+), 12 deletions(-) rename .eslintrc.js => .eslintrc.cjs (100%) diff --git a/.eslintrc.js b/.eslintrc.cjs similarity index 100% rename from .eslintrc.js rename to .eslintrc.cjs diff --git a/package.json b/package.json index 9087c81..7708b5f 100644 --- a/package.json +++ b/package.json @@ -9,14 +9,13 @@ ], "version": "1.0.0", "description": "Adyen Document Viewer", - "main": "./dist/adyen-document-viewer.min.js", + "main": "./dist/adyen-document-viewer.min.umd.cjs", + "module": "./dist/adyen-document-viewer.min.js", "type": "module", "types": "./dist/index.d.ts", "scripts": { - "clean": "rm -rf dist", - "dev": "vite", + "start": "vite", "build": "vite build && npm run types:build", - "preview": "vite preview", "lint": "eslint 'src/**/*.{js,ts,tsx}'", "lint:fix": "npm run lint -- --fix", "types:build": "tsc --project tsconfig-build.json", @@ -42,6 +41,7 @@ "stylelint-config-sass-guidelines": "^9.0.1", "stylelint-scss": "^4.2.0", "typescript": "^5.3.3", + "typescript-strict-plugin": "^2.2.0", "vite": "^4.5.1" }, "license": "SEE LICENSE IN LICENSE", @@ -54,16 +54,17 @@ "dist/adyen-document-viewer.min.umd.cjs", "dist/adyen-document-viewer.min.css", "dist/index.d.ts", + "dist/types/index.d.ts", "LICENSE", "README" ], "exports": { - "./adyen-document-viewer.min.js": { + ".": { "types": "./dist/index.d.ts", "import": "./dist/adyen-document-viewer.min.js", "require": "./dist/adyen-document-viewer.min.umd.cjs" }, - "./adyen-document-viewer.min.css": "./dist/adyen-document-viewer.min.css" + "./dist/adyen-document-viewer.min.css": "./dist/adyen-document-viewer.min.css" }, "optionalDependencies": { "@rollup/rollup-darwin-x64": "^4.9.1" diff --git a/tsconfig-build.json b/tsconfig-build.json index b1a0199..3582b56 100644 --- a/tsconfig-build.json +++ b/tsconfig-build.json @@ -4,7 +4,9 @@ "files": ["src/index.tsx", "node_modules/vite/client.d.ts", "src/scss.d.ts"], "compilerOptions": { "rootDir": "src", + "outDir": "dist", "noEmit": false, - "emitDeclarationOnly": true + "emitDeclarationOnly": true, + "declaration": true } } \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 5155153..c029e80 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,6 +15,7 @@ "react": ["./node_modules/preact/compat/"], "react-dom": ["./node_modules/preact/compat/"], }, + "plugins": [{ "name": "typescript-strict-plugin" }] }, "include": ["node_modules/vite/client.d.ts", "src/**/*"], } diff --git a/vite.config.ts b/vite.config.ts index 2e8e007..58a285d 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,19 +1,18 @@ -import dns from 'node:dns'; +import { setDefaultResultOrder } from 'node:dns'; import { resolve } from 'node:path'; import { defineConfig } from 'vite'; import preact from '@preact/preset-vite'; // This forces Vite to use `localhost` instead of `127.0.0.1`. Otherwise, we run into CORS issues // since `localhost:8080` and `localhost:8082` are same-origin, but `127.0.0.1:8082` isn't. -dns.setDefaultResultOrder('verbatim'); +setDefaultResultOrder('verbatim'); // https://vitejs.dev/config/ export default defineConfig(() => { return { css: { - modules: { - // Remove this after changing all of our SCSS @import to @use + // TODO: Remove this after changing all of our SCSS @import to @use scopeBehaviour: 'local', generateScopedName: (name) => name, }, @@ -27,7 +26,7 @@ export default defineConfig(() => { }, rollupOptions: { output: { - assetFileNames: "adyen-document-viewer.[ext]", + assetFileNames: 'adyen-document-viewer.min.[ext]', }, }, minify: true, From 05d8cb30ff819ceebe0e0686a23156b32b224964 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 8 Mar 2024 13:21:47 +0000 Subject: [PATCH 12/16] Update actions/setup-node action to v4 --- .github/workflows/npm-publish.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index 487e98a..64296d6 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 16 - run: npm i @@ -22,7 +22,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 16 registry-url: https://registry.npmjs.org/ From dd10afa2e9ab9e74e56be8d27c0e382763a225d5 Mon Sep 17 00:00:00 2001 From: George Iuriet <80108104+georgefromadyen@users.noreply.github.com> Date: Fri, 8 Mar 2024 14:32:28 +0100 Subject: [PATCH 13/16] Bump node-version --- .github/workflows/npm-publish.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index 64296d6..23bf315 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -14,7 +14,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: 16 + node-version: 18 - run: npm i publish-npm: @@ -24,7 +24,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: 16 + node-version: 18 registry-url: https://registry.npmjs.org/ - run: npm i - run: npm run build From 67d2210b37af71f82b55452fe8e1c534a8c4ec4f Mon Sep 17 00:00:00 2001 From: georgei Date: Fri, 8 Mar 2024 14:51:05 +0100 Subject: [PATCH 14/16] Remove @prefresh/babel-plugin dependency --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 7708b5f..1230409 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,6 @@ }, "devDependencies": { "@preact/preset-vite": "^2.8.1", - "@prefresh/babel-plugin": "^0.5.0", "@typescript-eslint/eslint-plugin": "^6.19.1", "@typescript-eslint/parser": "^6.19.1", "classnames": "^2.5.1", From 6952e75cbf9cae0030a0a22207523314869c0e97 Mon Sep 17 00:00:00 2001 From: georgei Date: Fri, 8 Mar 2024 14:53:37 +0100 Subject: [PATCH 15/16] Move classnames and preact to dependencies --- package.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 1230409..be63ee3 100644 --- a/package.json +++ b/package.json @@ -22,17 +22,19 @@ "types:check": "tsc && tsc-strict", "types:watch": "tsc --watch --preserveWatchOutput" }, + "dependencies": { + "classnames": "2.5.1", + "preact": "10.19.3" + }, "devDependencies": { "@preact/preset-vite": "^2.8.1", "@typescript-eslint/eslint-plugin": "^6.19.1", "@typescript-eslint/parser": "^6.19.1", - "classnames": "^2.5.1", "eslint": "^8.12.0", "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-import": "^2.29.1", "eslint-plugin-jsx-a11y": "^6.8.0", "eslint-plugin-react": "^7.33.2", - "preact": "^10.19.3", "prettier": "3.2.4", "sass": "^1.70.0", "stylelint": "^14.1.0", From fdf3faec0c3fbfb19b12adb2a989ed6640b076b8 Mon Sep 17 00:00:00 2001 From: georgei Date: Fri, 8 Mar 2024 15:03:26 +0100 Subject: [PATCH 16/16] Bump version to 1.0.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index be63ee3..3e5cdaa 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "viewer", "adyen-document-viewer" ], - "version": "1.0.0", + "version": "1.0.1", "description": "Adyen Document Viewer", "main": "./dist/adyen-document-viewer.min.umd.cjs", "module": "./dist/adyen-document-viewer.min.js",