Skip to content

Commit

Permalink
build: Implement eslint rules to move style prop in the bottom of the…
Browse files Browse the repository at this point in the history
… class (#615)

* setup

* format styles
  • Loading branch information
nielslyngsoe authored Oct 17, 2023
1 parent bb839af commit fdb6c84
Show file tree
Hide file tree
Showing 87 changed files with 4,157 additions and 4,056 deletions.
4 changes: 3 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module.exports = {
ignorePatterns: ['vite.*.js', 'packages/**/*.js', 'src/**/*'],
root: true,
plugins: ['html', 'import'],
plugins: ['html', 'import', 'eslint-plugin-local-rules'],
overrides: [
{
files: ['*.ts', '*.tsx'],
Expand All @@ -25,6 +25,8 @@ module.exports = {
'@typescript-eslint/ban-types': 'off', //TODO: Remove (maybe)
'lit/no-useless-template-literals': 'error',
'lit/prefer-nothing': 'error',
'local-rules/uui-class-prefix': 'warn',
'local-rules/prefer-static-styles-last': 'warn',
},
parserOptions: {
project: './tsconfig.json',
Expand Down
88 changes: 88 additions & 0 deletions eslint-local-rules.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
'use strict';

// eslint-disable-next-line no-undef
module.exports = {
/** @type {import('eslint').Rule.RuleModule} */
'uui-class-prefix': {
meta: {
type: 'problem',
docs: {
description:
'Ensure that all class declarations are prefixed with "UUI"',
category: 'Best Practices',
recommended: true,
},
schema: [],
},
create: function (context) {
function checkClassName(node) {
if (node.id && node.id.name && !node.id.name.startsWith('UUI')) {
context.report({
node: node.id,
message: 'Class declaration should be prefixed with "UUI"',
});
}
}

return {
ClassDeclaration: checkClassName,
};
},
},

/** @type {import('eslint').Rule.RuleModule}*/
'prefer-static-styles-last': {
meta: {
type: 'suggestion',
docs: {
description:
'Enforce the "styles" property with the static modifier to be the last property of a class that ends with "Element".',
category: 'Best Practices',
recommended: true,
},
fixable: 'code',
schema: [],
},
create: function (context) {
return {
ClassDeclaration(node) {
const className = node.id.name;
if (className.endsWith('Element')) {
const staticStylesProperty = node.body.body.find(bodyNode => {
return (
bodyNode.type === 'PropertyDefinition' &&
bodyNode.key.name === 'styles' &&
bodyNode.static
);
});
if (staticStylesProperty) {
const lastProperty = node.body.body[node.body.body.length - 1];
if (lastProperty.key.name !== staticStylesProperty.key.name) {
context.report({
node: staticStylesProperty,
message:
'The "styles" property should be the last property of a class declaration.',
data: {
className: className,
},
fix: function (fixer) {
const sourceCode = context.getSourceCode();
const staticStylesPropertyText =
sourceCode.getText(staticStylesProperty);
return [
fixer.replaceTextRange(staticStylesProperty.range, ''),
fixer.insertTextAfterRange(
lastProperty.range,
'\n \n ' + staticStylesPropertyText
),
];
},
});
}
}
}
},
};
},
},
};
11 changes: 10 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
"eslint-plugin-import": "2.27.5",
"eslint-plugin-lit": "1.8.3",
"eslint-plugin-lit-a11y": "4.1.0",
"eslint-plugin-local-rules": "^2.0.0",
"eslint-plugin-storybook": "0.6.14",
"eslint-plugin-wc": "1.5.0",
"github-markdown-css": "5.2.0",
Expand Down
42 changes: 21 additions & 21 deletions packages/uui-avatar-group/lib/uui-avatar-group.element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,6 @@ import { property, queryAssignedElements, state } from 'lit/decorators.js';
*/
@defineElement('uui-avatar-group')
export class UUIAvatarGroupElement extends LitElement {
static styles = [
css`
:host {
display: inline-flex;
align-items: center;
padding-left: 3px;
padding-right: 3px;
}
::slotted(uui-avatar) {
margin-left: -0.2em;
margin-right: -0.2em;
border: 0.1em solid var(--uui-avatar-border-color);
}
#overflow-indication {
margin-left: 6px;
}
`,
];

@queryAssignedElements({
selector: 'uui-avatar, [uui-avatar]',
flatten: true,
Expand Down Expand Up @@ -88,6 +67,27 @@ export class UUIAvatarGroupElement extends LitElement {
: ''}
`;
}

static styles = [
css`
:host {
display: inline-flex;
align-items: center;
padding-left: 3px;
padding-right: 3px;
}
::slotted(uui-avatar) {
margin-left: -0.2em;
margin-right: -0.2em;
border: 0.1em solid var(--uui-avatar-border-color);
}
#overflow-indication {
margin-left: 6px;
}
`,
];
}

declare global {
Expand Down
70 changes: 35 additions & 35 deletions packages/uui-avatar/lib/uui-avatar.element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,41 +9,6 @@ import { property, state } from 'lit/decorators.js';
*/
@defineElement('uui-avatar')
export class UUIAvatarElement extends LitElement {
static styles = [
css`
:host {
display: inline-flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
position: relative;
overflow: hidden;
border-radius: 50%;
font-weight: 700;
-webkit-font-smoothing: subpixel-antialiased;
width: calc(2em + 4px);
height: calc(2em + 4px);
user-select: none;
/* box-sizing: border-box; */
aspect-ratio: 1;
background-color: var(--uui-palette-spanish-pink);
color: var(--uui-palette-space-cadet);
}
:host([overflow]) {
overflow: unset;
}
img {
object-fit: cover;
height: 100%;
width: 100%;
overflow: hidden;
border-radius: 50%;
}
`,
];

/**
* Set to true to prevent content from getting hidden if going outside the parent. Useful in combination with something like a Badge.
* @type {boolean}
Expand Down Expand Up @@ -136,6 +101,41 @@ export class UUIAvatarElement extends LitElement {
<slot></slot>
`;
}

static styles = [
css`
:host {
display: inline-flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
position: relative;
overflow: hidden;
border-radius: 50%;
font-weight: 700;
-webkit-font-smoothing: subpixel-antialiased;
width: calc(2em + 4px);
height: calc(2em + 4px);
user-select: none;
/* box-sizing: border-box; */
aspect-ratio: 1;
background-color: var(--uui-palette-spanish-pink);
color: var(--uui-palette-space-cadet);
}
:host([overflow]) {
overflow: unset;
}
img {
object-fit: cover;
height: 100%;
width: 100%;
overflow: hidden;
border-radius: 50%;
}
`,
];
}

declare global {
Expand Down
62 changes: 31 additions & 31 deletions packages/uui-badge/lib/uui-badge.element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,37 @@ import type {

@defineElement('uui-badge')
export class UUIBadgeElement extends LitElement {
/**
* Changes the look of the button to one of the predefined, symbolic looks. For example - set this to positive if you want nice, green "confirm" button.
* @type {"default" | "positive" | "warning" | "danger"}
* @attr
* @default "default"
*/
@property({ reflect: true })
color: InterfaceColor = 'default';

/**
* Changes the look of the button to one of the predefined, symbolic looks. For example - set this to positive if you want nice, green "confirm" button.
* @type {"default" | "primary" | "secondary" | "outline" | "placeholder"}
* @attr
* @default "default"
*/
@property({ reflect: true })
look: InterfaceLook = 'primary';

/**
* Bring attention to this badge by applying a bounce animation.
* @type Boolean
* @attr
* @default false
*/
@property({ type: Boolean, reflect: true })
attention = false;

render() {
return html` <slot></slot> `;
}

static styles = [
css`
:host {
Expand Down Expand Up @@ -127,37 +158,6 @@ export class UUIBadgeElement extends LitElement {
}
`,
];

/**
* Changes the look of the button to one of the predefined, symbolic looks. For example - set this to positive if you want nice, green "confirm" button.
* @type {"default" | "positive" | "warning" | "danger"}
* @attr
* @default "default"
*/
@property({ reflect: true })
color: InterfaceColor = 'default';

/**
* Changes the look of the button to one of the predefined, symbolic looks. For example - set this to positive if you want nice, green "confirm" button.
* @type {"default" | "primary" | "secondary" | "outline" | "placeholder"}
* @attr
* @default "default"
*/
@property({ reflect: true })
look: InterfaceLook = 'primary';

/**
* Bring attention to this badge by applying a bounce animation.
* @type Boolean
* @attr
* @default false
*/
@property({ type: Boolean, reflect: true })
attention = false;

render() {
return html` <slot></slot> `;
}
}

declare global {
Expand Down
Loading

0 comments on commit fdb6c84

Please sign in to comment.