diff --git a/apps/contrast-plugin/.babelrc b/apps/contrast-plugin/.babelrc deleted file mode 100644 index f2f3806..0000000 --- a/apps/contrast-plugin/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@nx/js/babel"] -} diff --git a/apps/contrast-plugin/.swcrc b/apps/contrast-plugin/.swcrc deleted file mode 100644 index a2d5b04..0000000 --- a/apps/contrast-plugin/.swcrc +++ /dev/null @@ -1,8 +0,0 @@ -{ - "jsc": { - "parser": { - "syntax": "typescript" - }, - "target": "es2016" - } -} diff --git a/apps/contrast-plugin/eslint.config.js b/apps/contrast-plugin/eslint.config.js index ad49d00..29c2176 100644 --- a/apps/contrast-plugin/eslint.config.js +++ b/apps/contrast-plugin/eslint.config.js @@ -1,25 +1,43 @@ import baseConfig from '../../eslint.config.js'; -import typescriptEslintParser from '@typescript-eslint/parser'; +import { compat } from '../../eslint.base.config.js'; export default [ ...baseConfig, - { - languageOptions: { - parser: typescriptEslintParser, - parserOptions: { project: './apps/contrast-plugin/tsconfig.app.json' }, - }, - }, - { - files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'], - rules: {}, - }, - { - files: ['**/*.ts', '**/*.tsx'], - rules: {}, - }, - { - files: ['**/*.js', '**/*.jsx'], - rules: {}, - }, - { ignores: ['vite.config.ts'] }, + ...compat + .config({ + extends: [ + 'plugin:@nx/angular', + 'plugin:@angular-eslint/template/process-inline-templates', + ], + }) + .map((config) => ({ + ...config, + files: ['**/*.ts'], + rules: { + '@angular-eslint/directive-selector': [ + 'error', + { + type: 'attribute', + prefix: 'app', + style: 'camelCase', + }, + ], + '@angular-eslint/component-selector': [ + 'error', + { + type: 'element', + prefix: 'app', + style: 'kebab-case', + }, + ], + }, + })), + ...compat + .config({ extends: ['plugin:@nx/angular-template'] }) + .map((config) => ({ + ...config, + files: ['**/*.html'], + rules: {}, + })), + { ignores: ['**/assets/*.js'] }, ]; diff --git a/apps/contrast-plugin/project.json b/apps/contrast-plugin/project.json index 497af03..20bd11f 100644 --- a/apps/contrast-plugin/project.json +++ b/apps/contrast-plugin/project.json @@ -2,7 +2,92 @@ "name": "contrast-plugin", "$schema": "../../node_modules/nx/schemas/project-schema.json", "projectType": "application", + "prefix": "app", "sourceRoot": "apps/contrast-plugin/src", "tags": ["type:plugin"], - "targets": {} + "targets": { + "build": { + "executor": "@angular-devkit/build-angular:application", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/apps/contrast-plugin", + "index": "apps/contrast-plugin/src/index.html", + "browser": "apps/contrast-plugin/src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "apps/contrast-plugin/tsconfig.app.json", + "assets": [ + "apps/contrast-plugin/src/favicon.ico", + "apps/contrast-plugin/src/assets" + ], + "styles": [ + "libs/plugins-styles/src/lib/styles.css", + "apps/contrast-plugin/src/styles.css" + ], + "scripts": [], + "optimization": { + "scripts": true, + "styles": true, + "fonts": false + } + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kb", + "maximumError": "1mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "2kb", + "maximumError": "4kb" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "executor": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "contrast-plugin:build:production" + }, + "development": { + "buildTarget": "contrast-plugin:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "executor": "@angular-devkit/build-angular:extract-i18n", + "options": { + "buildTarget": "contrast-plugin:build" + } + }, + "buildPlugin": { + "executor": "@nx/esbuild:esbuild", + "outputs": [ + "{options.outputPath}" + ], + "options": { + "minify": true, + "outputPath": "apps/contrast-plugin/src/assets/", + "main": "apps/contrast-plugin/src/plugin.ts", + "tsConfig": "apps/contrast-plugin/tsconfig.plugin.json", + "generatePackageJson": false, + "format": [ + "esm" + ], + "deleteOutputPath": false + } + }, + } } diff --git a/apps/contrast-plugin/public/manifest.json b/apps/contrast-plugin/public/manifest.json deleted file mode 100644 index f504ea4..0000000 --- a/apps/contrast-plugin/public/manifest.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "Contrast plugin", - "host": "http://localhost:4302", - "code": "/plugin.js", - "icon": "/icon.png", - "permissions": [ - "page:read", - "file:read", - "selection:read" - ] -} diff --git a/apps/contrast-plugin/src/app/app.component.css b/apps/contrast-plugin/src/app/app.component.css new file mode 100644 index 0000000..f911b90 --- /dev/null +++ b/apps/contrast-plugin/src/app/app.component.css @@ -0,0 +1,77 @@ +.wrapper { + padding-block-start: var(--spacing-24); +} + +.bold { + font-weight: 600; +} + +.contrast-preview { + display: flex; + flex-direction: column; + gap: var(--spacing-8); + padding-block-end: var(--spacing-20); + border-block-end: 2px solid var(--background-quaternary); +} + +.color-box { + block-size: 66px; + border-radius: var(--spacing-8); + background: linear-gradient( + to right, + var(--color1) 0%, + var(--color1) 50%, + var(--color2) 50%, + var(--color2) 100% + ); +} + +.select-colors { + display: flex; + justify-content: space-between; +} + +.contrast-ratio { + padding-block: var(--spacing-24); + + span { + color: var(--foreground-primary); + } +} + +.contrast-results { + display: flex; + flex-direction: column; + gap: var(--spacing-16); +} + +.contrast-result { + .title { + margin-block-end: var(--spacing-4); + } + .list { + display: flex; + gap: var(--spacing-8); + } +} + +.tag { + display: flex; + align-items: center; + justify-content: center; + inline-size: 42px; + block-size: 32px; + color: var(--app-white); + border: 1px solid transparent; + border-radius: var(--spacing-8); + + &.good { + background-color: var(--success-950); + border-color: var(--success-500); + } + + &.fail { + background-color: var(--error-950); + border-color: var(--error-700); + } +} diff --git a/apps/contrast-plugin/src/app/app.component.ts b/apps/contrast-plugin/src/app/app.component.ts new file mode 100644 index 0000000..1748ff3 --- /dev/null +++ b/apps/contrast-plugin/src/app/app.component.ts @@ -0,0 +1,231 @@ +import { + ChangeDetectionStrategy, + Component, + computed, + inject, +} from '@angular/core'; +import { toSignal } from '@angular/core/rxjs-interop'; +import { ActivatedRoute } from '@angular/router'; +import type { + PluginMessageEvent, + PluginUIEvent, + ThemePluginEvent, +} from '../model'; +import { filter, fromEvent, map, merge, take } from 'rxjs'; +import { CommonModule } from '@angular/common'; +import { PenpotShape } from '@penpot/plugin-types'; + +@Component({ + standalone: true, + imports: [CommonModule], + selector: 'app-root', + template: ` +
+ @if (selection().length === 0) { +

+ Select two filled shapes to calculate the color contrast between them. +

+ } @else if (selection().length === 1) { +

+ Select one more filled shape to calculate the + color contrast between the selected colors. +

+ } @else if (selection().length >= 2) { +
+

Selected colors:

+
+ +
+

+ Contrast ratio: {{ result() }} : 1 +

+
+
+

Normal text:

+
    +
  • + AA +
  • +
  • + AAA +
  • +
+
+
+

+ Large text + (starting from 19px bold or 24px): +

+
    +
  • + AA +
  • +
  • + AAA +
  • +
+
+
+

+ Graphics (such as form input borders): +

+
    +
  • + AA +
  • +
+
+
+ } +
+ `, + styleUrl: './app.component.css', + host: { + '[attr.data-theme]': 'theme()', + '[style.--color1]': 'color1()', + '[style.--color2]': 'color2()', + }, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class AppComponent { + #route = inject(ActivatedRoute); + #messages$ = fromEvent>(window, 'message'); + + #initialTheme$ = this.#route.queryParamMap.pipe( + map((params) => params.get('theme')), + filter((theme) => !!theme), + take(1) + ); + + selection = toSignal( + this.#messages$.pipe( + filter( + (event) => event.data.type === 'init' || event.data.type === 'selection' + ), + map((event) => { + if (event.data.type === 'init') { + return event.data.content.selection; + } else if (event.data.type === 'selection') { + return event.data.content; + } + + return []; + }), + map((shapes) => { + return shapes + .map((shape) => this.#getShapeColor(shape)) + .filter((color): color is string => !!color); + }) + ), + { + initialValue: [], + } + ); + + theme = toSignal( + merge( + this.#initialTheme$, + this.#messages$.pipe( + map((event) => event.data), + filter((data): data is ThemePluginEvent => data.type === 'theme'), + map((data) => { + return data.content; + }) + ) + ) + ); + + color1 = computed(() => { + return this.selection().at(-2); + }); + + color2 = computed(() => { + return this.selection().at(-1); + }); + + result = computed(() => { + const color1 = this.color1(); + const color2 = this.color2(); + + if (!color1 || !color2) { + return 0; + } + + const lum1 = this.#getLuminosity(color1) + 0.05; + const lum2 = this.#getLuminosity(color2) + 0.05; + + const result = lum1 > lum2 ? lum1 / lum2 : lum2 / lum1; + + return Number(result.toFixed(2)); + }); + + contrastStandards = { + AA: { + normal: 4.5, + large: 3, + }, + AAA: { + normal: 7, + large: 4.5, + }, + graphics: 3, + } as const; + + constructor() { + this.#sendMessage({ type: 'ready' }); + } + + #getLuminosity(color: string) { + const rgb = this.#hexToRgb(color); + const a = rgb.map((v) => { + v /= 255; + return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4); + }); + return 0.2126 * a[0] + 0.7152 * a[1] + 0.0722 * a[2]; + } + + #hexToRgb(hex: string) { + const r = parseInt(hex.slice(1, 3), 16); + const g = parseInt(hex.slice(3, 5), 16); + const b = parseInt(hex.slice(5, 7), 16); + return [r, g, b]; + } + + #getShapeColor(shape?: PenpotShape): string | undefined { + return shape?.fills?.[0]?.fillColor ?? shape?.strokes?.[0]?.strokeColor; + } + + #sendMessage(message: PluginUIEvent) { + parent.postMessage(message, '*'); + } +} diff --git a/apps/contrast-plugin/src/app/app.config.ts b/apps/contrast-plugin/src/app/app.config.ts new file mode 100644 index 0000000..1b3e4af --- /dev/null +++ b/apps/contrast-plugin/src/app/app.config.ts @@ -0,0 +1,6 @@ +import { ApplicationConfig } from '@angular/core'; +import { provideRouter } from '@angular/router'; + +export const appConfig: ApplicationConfig = { + providers: [provideRouter([])], +}; diff --git a/apps/contrast-plugin/src/app/app.element.css b/apps/contrast-plugin/src/app/app.element.css deleted file mode 100644 index 542fb3e..0000000 --- a/apps/contrast-plugin/src/app/app.element.css +++ /dev/null @@ -1,101 +0,0 @@ -.wrapper { - &[data-theme='dark'] { - color: var(--app-white); - } - - &[data-theme='light'] { - color: var(--app-black); - } -} - -.color { - align-items: center; - display: flex; - margin-inline-end: var(--spacing-16); -} - -.color-preview { - block-size: var(--spacing-36); - border: 1px solid var(--df-secondary); - border-radius: var(--spacing-4); - display: block; - inline-size: var(--spacing-36); - margin-inline-end: var(--spacing-16); -} - -.fail { - background-color: var(--error-500); -} - -.good { - background-color: var(--success-500); -} - -.title { - margin-block-end: var(--spacing-8); -} - -.list { - display: flex; - margin-block-end: var(--spacing-16); -} - -.tag { - border-radius: var(--spacing-4); - color: var(--db-primary); - margin-inline-end: var(--spacing-16); - padding: var(--spacing-4) var(--spacing-8); - text-transform: uppercase; -} - -.contrast-preview { - align-items: center; - border: 1px solid var(--df-secondary); - border-radius: var(--spacing-4); - box-sizing: content-box; - block-size: calc(2 * var(--spacing-40)); - display: flex; - flex-direction: column; - justify-content: center; - inline-size: calc(100% - var(--spacing-16)); - margin-block-end: var(--spacing-16); - padding-block: var(--spacing-24); -} - -.empty-preview { - position: absolute; -} - -.text { - color: transparent; - margin-block-end: var(--spacing-8); - - &.small { - font-size: 18px; - } - - &.large { - font-size: 24px; - } -} - -.icons-list { - display: flex; - gap: var(--spacing-8); - margin-block-start: var(--spacing-8); -} - -.shape { - block-size: var(--spacing-24); - inline-size: var(--spacing-24); -} - -.circle { - border-radius: 50%; -} - -.triangle { - border-left: var(--spacing-12) solid transparent; - border-right: var(--spacing-12) solid transparent; - border-bottom: var(--spacing-24) solid transparent; -} diff --git a/apps/contrast-plugin/src/app/app.element.ts b/apps/contrast-plugin/src/app/app.element.ts deleted file mode 100644 index 1528db1..0000000 --- a/apps/contrast-plugin/src/app/app.element.ts +++ /dev/null @@ -1,212 +0,0 @@ -/* eslint-disable */ -import 'plugins-styles/lib/styles.css'; -import './app.element.css'; - -export class AppElement extends HTMLElement { - public static observedAttributes = []; - public shapes: any; - - calculateContrast(firstColor: string, secondColor: string) { - const luminosityFirstColor = this.getLuminosity(firstColor); - const luminositySecondColor = this.getLuminosity(secondColor); - - const result = - (luminosityFirstColor + 0.05) / (luminositySecondColor + 0.05); - - this.setColors(firstColor, secondColor); - this.setResult(result.toFixed(2).toString()); - this.setA11yTags(result); - } - - getLuminosity(color: string) { - const rgb = this.hexToRgb(color); - const a = rgb.map((v) => { - v /= 255; - return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4); - }); - return 0.2126 * a[0] + 0.7152 * a[1] + 0.0722 * a[2]; - } - - hexToRgb(hex: string) { - const r = parseInt(hex.slice(1, 3), 16); - const g = parseInt(hex.slice(3, 5), 16); - const b = parseInt(hex.slice(5, 7), 16); - return [r, g, b]; - } - - setResult(text: string) { - const selector = document.getElementById('result'); - - if (selector) { - selector.innerText = `${text} : 1`; - } - } - - setColors(firstColor: string | null, secondColor: string | null) { - const color1 = document.getElementById('first-color'); - const color2 = document.getElementById('second-color'); - const code1 = document.getElementById('first-color-code'); - const code2 = document.getElementById('second-color-code'); - const contrastPreview = document.getElementById('contrast-preview'); - const smallText = document.getElementById('small-text'); - const largeText = document.getElementById('large-text'); - const circle = document.getElementById('circle'); - const square = document.getElementById('square'); - const triangle = document.getElementById('triangle'); - - if (color1 && code1) { - color1.style.background = firstColor ? firstColor : 'transparent'; - code1.innerText = firstColor ? firstColor : ''; - } - - if (color2 && code2) { - color2.style.background = secondColor ? secondColor : 'transparent'; - code2.innerText = secondColor ? secondColor : ''; - } - - if ( - contrastPreview && - smallText && - largeText && - circle && - square && - triangle - ) { - contrastPreview.style.background = secondColor - ? secondColor - : 'transparent'; - smallText.style.color = firstColor ? firstColor : 'transparent'; - largeText.style.color = firstColor ? firstColor : 'transparent'; - circle.style.background = firstColor ? firstColor : 'transparent'; - square.style.background = firstColor ? firstColor : 'transparent'; - triangle.style.borderBottom = firstColor - ? `var(--spacing-24) solid ${firstColor}` - : 'var(--spacing-24) solid transparent'; - } - - const emptyPreview = document.getElementById('empty-preview'); - if (!firstColor && !secondColor && emptyPreview) { - emptyPreview.style.display = 'block'; - } else if (emptyPreview) { - emptyPreview.style.display = 'none'; - } - } - - setA11yTags(result: number) { - const selectors = { - aa: document.getElementById('aa'), - aaa: document.getElementById('aaa'), - aaLg: document.getElementById('aa-lg'), - aaaLg: document.getElementById('aaa-lg'), - graphics: document.getElementById('graphics'), - }; - const fail = 'tag fail'; - const good = 'tag good'; - - function setClass(selector: HTMLElement | null, className: string) { - if (selector) { - selector.className = className; - } - } - - if (result > 7) { - setClass(selectors.aa, good); - setClass(selectors.aaa, good); - setClass(selectors.aaLg, good); - setClass(selectors.aaaLg, good); - setClass(selectors.graphics, good); - } else if (result > 4.5) { - setClass(selectors.aa, good); - setClass(selectors.aaa, fail); - setClass(selectors.aaLg, good); - setClass(selectors.aaaLg, good); - setClass(selectors.graphics, good); - } else if (result > 3) { - setClass(selectors.aa, fail); - setClass(selectors.aaa, fail); - setClass(selectors.aaLg, good); - setClass(selectors.aaaLg, fail); - setClass(selectors.graphics, good); - } else { - setClass(selectors.aa, fail); - setClass(selectors.aaa, fail); - setClass(selectors.aaLg, fail); - setClass(selectors.aaaLg, fail); - setClass(selectors.graphics, fail); - } - } - - initCalculate(shapes: any) { - const obj0 = shapes[0]?.fills?.[0]?.fillColor; - const obj1 = shapes[1]?.fills?.[0]?.fillColor; - - if (obj0 && obj1) { - this.calculateContrast(obj0, obj1); - } - } - - connectedCallback() { - window.addEventListener('message', (event) => { - if (event.data.type === 'init') { - this.setAttribute('data-theme', event.data.content.theme); - if (event.data.content.selection.length >= 2) { - this.initCalculate(event.data.content.shapes); - } - } else if (event.data.type === 'selection') { - if (event.data.content.shapes.length >= 2) { - this.initCalculate(event.data.content.shapes); - } else { - this.setColors(null, null); - this.setResult('0'); - this.setA11yTags(0); - } - } else if (event.data.type === 'theme') { - this.setAttribute('data-theme', event.data.content.theme); - } - }); - - this.innerHTML = ` -
-
-

Select two colors to calculate contrast

-

SMALL sample text

-

LARGE sample text

-
    - - - -
-
-

Selected colors:

-
    -
  • - - -
  • -
  • - - -
  • -
-

Contrast ratio: 0 : 1

-

Normal text:

-
    -
  • AA
  • -
  • AAA
  • -
-

Large text (24px or 19px + bold):

-
    -
  • AA
  • -
  • AAA
  • -
-

Graphics (such as form input borders):

-
    -
  • AA
  • -
-
- `; - - parent.postMessage({ content: 'ready' }, '*'); - } -} -customElements.define('app-root', AppElement); diff --git a/apps/contrast-plugin/src/assets/.gitkeep b/apps/contrast-plugin/src/assets/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/apps/contrast-plugin/src/assets/manifest.json b/apps/contrast-plugin/src/assets/manifest.json new file mode 100644 index 0000000..0870e1e --- /dev/null +++ b/apps/contrast-plugin/src/assets/manifest.json @@ -0,0 +1,7 @@ +{ + "name": "Contrast", + "host": "http://localhost:4302", + "description": "Measure contrast plugin", + "code": "/assets/plugin.js", + "permissions": ["page:read", "file:read", "selection:read"] +} diff --git a/apps/contrast-plugin/index.html b/apps/contrast-plugin/src/index.html similarity index 52% rename from apps/contrast-plugin/index.html rename to apps/contrast-plugin/src/index.html index 88aef45..5326791 100644 --- a/apps/contrast-plugin/index.html +++ b/apps/contrast-plugin/src/index.html @@ -2,15 +2,11 @@ - ContrastPlugin + contrast-plugin - - - - diff --git a/apps/contrast-plugin/src/main.ts b/apps/contrast-plugin/src/main.ts index fdb879d..514c89a 100644 --- a/apps/contrast-plugin/src/main.ts +++ b/apps/contrast-plugin/src/main.ts @@ -1 +1,7 @@ -import './app/app.element'; +import { bootstrapApplication } from '@angular/platform-browser'; +import { appConfig } from './app/app.config'; +import { AppComponent } from './app/app.component'; + +bootstrapApplication(AppComponent, appConfig).catch((err) => + console.error(err) +); diff --git a/apps/contrast-plugin/src/model.ts b/apps/contrast-plugin/src/model.ts new file mode 100644 index 0000000..214a79e --- /dev/null +++ b/apps/contrast-plugin/src/model.ts @@ -0,0 +1,29 @@ +import { PenpotShape } from '@penpot/plugin-types'; + +export interface InitPluginUIEvent { + type: 'ready'; +} + +export type PluginUIEvent = InitPluginUIEvent; + +export interface InitPluginEvent { + type: 'init'; + content: { + theme: string; + selection: PenpotShape[]; + }; +} +export interface SelectionPluginEvent { + type: 'selection'; + content: PenpotShape[]; +} + +export interface ThemePluginEvent { + type: 'theme'; + content: string; +} + +export type PluginMessageEvent = + | InitPluginEvent + | SelectionPluginEvent + | ThemePluginEvent; diff --git a/apps/contrast-plugin/src/plugin.ts b/apps/contrast-plugin/src/plugin.ts index 1c5e866..07386c5 100644 --- a/apps/contrast-plugin/src/plugin.ts +++ b/apps/contrast-plugin/src/plugin.ts @@ -1,15 +1,17 @@ -penpot.ui.open('Contrast plugin', '', { - width: 450, - height: 625, +import type { PluginMessageEvent, PluginUIEvent } from './model.js'; + +penpot.ui.open('CONTRAST PLUGIN', `?theme=${penpot.getTheme()}`, { + width: 235, + height: 445, }); -penpot.ui.onMessage<{ content: string }>((message) => { - if (message.content === 'ready') { - penpot.ui.sendMessage({ +penpot.ui.onMessage((message) => { + if (message.type === 'ready') { + sendMessage({ type: 'init', content: { theme: penpot.getTheme(), - shapes: penpot.getSelectedShapes(), + selection: penpot.getSelectedShapes(), }, }); } @@ -17,10 +19,14 @@ penpot.ui.onMessage<{ content: string }>((message) => { penpot.on('selectionchange', () => { const shapes = penpot.getSelectedShapes(); - penpot.ui.sendMessage({ type: 'selection', content: { shapes } }); + sendMessage({ type: 'selection', content: shapes }); }); penpot.on('themechange', () => { const theme = penpot.getTheme(); - penpot.ui.sendMessage({ type: 'theme', content: { theme } }); + sendMessage({ type: 'theme', content: theme }); }); + +function sendMessage(message: PluginMessageEvent) { + penpot.ui.sendMessage(message); +} diff --git a/apps/contrast-plugin/src/styles.css b/apps/contrast-plugin/src/styles.css index 90d4ee0..e69de29 100644 --- a/apps/contrast-plugin/src/styles.css +++ b/apps/contrast-plugin/src/styles.css @@ -1 +0,0 @@ -/* You can add global styles to this file, and also import other style files */ diff --git a/apps/contrast-plugin/tsconfig.app.json b/apps/contrast-plugin/tsconfig.app.json index 559b7d6..936913d 100644 --- a/apps/contrast-plugin/tsconfig.app.json +++ b/apps/contrast-plugin/tsconfig.app.json @@ -2,8 +2,9 @@ "extends": "./tsconfig.json", "compilerOptions": { "outDir": "../../dist/out-tsc", - "types": ["node"] + "types": [] }, - "exclude": ["src/**/*.spec.ts", "src/**/*.test.ts"], - "include": ["src/**/*.ts", "../../libs/plugin-types/index.d.ts"] + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"], + "exclude": ["src/**/*.test.ts", "src/**/*.spec.ts"] } diff --git a/apps/contrast-plugin/tsconfig.editor.json b/apps/contrast-plugin/tsconfig.editor.json new file mode 100644 index 0000000..4ee6393 --- /dev/null +++ b/apps/contrast-plugin/tsconfig.editor.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "include": ["src/**/*.ts"], + "compilerOptions": { + "types": [] + } +} diff --git a/apps/contrast-plugin/tsconfig.json b/apps/contrast-plugin/tsconfig.json index cee4bba..4c48587 100644 --- a/apps/contrast-plugin/tsconfig.json +++ b/apps/contrast-plugin/tsconfig.json @@ -1,30 +1,33 @@ { - "extends": "../../tsconfig.base.json", - "files": [], "compilerOptions": { - "target": "ESNext", - "useDefineForClassFields": true, - "module": "ESNext", - "lib": ["ESNext", "DOM"], - "moduleResolution": "Node", - "strict": true, - "resolveJsonModule": true, - "isolatedModules": true, + "target": "es2022", + "useDefineForClassFields": false, "esModuleInterop": true, - "noEmit": true, - "noUnusedLocals": true, - "noUnusedParameters": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, "noImplicitReturns": true, - "skipLibCheck": true, - "types": ["vite/client"] + "noFallthroughCasesInSwitch": true }, - "include": ["src"], + "files": [], + "include": [], "references": [ { "path": "./tsconfig.app.json" }, { - "path": "./tsconfig.spec.json" + "path": "./tsconfig.editor.json" + }, + { + "path": "./tsconfig.plugin.json" } - ] + ], + "extends": "../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } } diff --git a/apps/contrast-plugin/tsconfig.plugin.json b/apps/contrast-plugin/tsconfig.plugin.json new file mode 100644 index 0000000..961987f --- /dev/null +++ b/apps/contrast-plugin/tsconfig.plugin.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "types": [] + }, + "files": ["src/plugin.ts"], + "include": ["../../libs/plugin-types/index.d.ts"] +} diff --git a/apps/contrast-plugin/tsconfig.spec.json b/apps/contrast-plugin/tsconfig.spec.json deleted file mode 100644 index 3c002c2..0000000 --- a/apps/contrast-plugin/tsconfig.spec.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../dist/out-tsc", - "types": [ - "vitest/globals", - "vitest/importMeta", - "vite/client", - "node", - "vitest" - ] - }, - "include": [ - "vite.config.ts", - "vitest.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "src/**/*.test.tsx", - "src/**/*.spec.tsx", - "src/**/*.test.js", - "src/**/*.spec.js", - "src/**/*.test.jsx", - "src/**/*.spec.jsx", - "src/**/*.d.ts" - ] -} diff --git a/apps/contrast-plugin/vite.config.ts b/apps/contrast-plugin/vite.config.ts index 95c516e..c5ff14b 100644 --- a/apps/contrast-plugin/vite.config.ts +++ b/apps/contrast-plugin/vite.config.ts @@ -1,57 +1,19 @@ /// import { defineConfig } from 'vite'; -import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin'; - export default defineConfig({ root: __dirname, - cacheDir: '../../node_modules/.vite/apps/contrast-plugin', - - server: { - port: 4302, - host: '0.0.0.0', - }, - - preview: { - port: 4302, - host: '0.0.0.0', - }, - - plugins: [nxViteTsPaths()], - - // Uncomment this if you are using workers. - // worker: { - // plugins: [ nxViteTsPaths() ], - // }, - - build: { - outDir: '../../dist/apps/contrast-plugin', - reportCompressedSize: true, - commonjsOptions: { - transformMixedEsModules: true, - }, - rollupOptions: { - input: { - plugin: 'src/plugin.ts', - index: './index.html', - }, - output: { - entryFileNames: '[name].js', - }, - }, - }, - + cacheDir: '../node_modules/.vite/contrast-plugin', test: { globals: true, cache: { - dir: '../../node_modules/.vitest', + dir: '../node_modules/.vitest', }, environment: 'jsdom', include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], - reporters: ['default'], coverage: { - reportsDirectory: '../../coverage/apps/contrast-plugin', + reportsDirectory: '../coverage/contrast-plugin', provider: 'v8', }, }, diff --git a/libs/plugins-styles/src/lib/core/fonts.css b/libs/plugins-styles/src/lib/core/fonts.css index cbb5a88..005dc1a 100644 --- a/libs/plugins-styles/src/lib/core/fonts.css +++ b/libs/plugins-styles/src/lib/core/fonts.css @@ -7,6 +7,7 @@ --font-line-height-s: 1.2; --font-line-height-m: 1.4; --font-line-height-l: 1.5; + --font-size-xs: 10px; --font-size-s: 12px; --font-size-m: 14px; --font-size-l: 16px; @@ -68,6 +69,12 @@ code { text-transform: uppercase; } +.body-xs { + font-weight: var(--font-weight-regular); + font-size: var(--font-size-xs); + line-height: var(--font-line-height-s); +} + .body-s { font-weight: var(--font-weight-regular); font-size: var(--font-size-s); diff --git a/package.json b/package.json index d72e0e3..bf72043 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "start:plugin:all": "concurrently --kill-others \"npm:start:plugin:*(!all)\"", "start:plugin:poc-state": "npx nx run-many --targets=buildPlugin,serve --projects=poc-state-plugin --watch --host 0.0.0.0 --port 4301", - "start:plugin:contrast": "npx nx run contrast-plugin:build --watch & npx nx run contrast-plugin:preview", + "start:contrast-plugin": "npx nx run-many --targets=buildPlugin,serve --projects=contrast-plugin --watch --host 0.0.0.0 --port 4302", "start:plugin:icons": "npx nx run-many --targets=buildPlugin,serve --projects=icons-plugin --watch --host 0.0.0.0 --port 4303", "start:plugin:loremipsum": "npx nx run-many --targets=buildPlugin,serve --projects=lorem-ipsum-plugin --watch --port 4304", "start:plugin:palette": "npx nx run create-palette-plugin:build --watch & npx nx run create-palette-plugin:preview", diff --git a/tsconfig.base.json b/tsconfig.base.json index 316b398..cdc4da8 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -10,7 +10,7 @@ "importHelpers": true, "target": "es2015", "module": "esnext", - "lib": ["es2020", "dom"], + "lib": ["es2022", "dom"], "skipLibCheck": true, "skipDefaultLibCheck": true, "baseUrl": ".",