mirror of
https://github.com/navikt/aksel.git
synced 2026-10-14 09:42:02 +00:00
Compare commits
12
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
239017b07a | ||
|
|
7615dbbb54 | ||
|
|
4034eea298 | ||
|
|
68501b4c8a | ||
|
|
61c4114214 | ||
|
|
b958d41a20 | ||
|
|
c3905aa2f8 | ||
|
|
812a2347a0 | ||
|
|
deb1c151bb | ||
|
|
784d17165d | ||
|
|
1a894829f0 | ||
|
|
e06a76b5c5 |
No files matched your search
@@ -13,7 +13,8 @@
|
||||
"@navikt/ds-codemod",
|
||||
"@navikt/aksel-icons",
|
||||
"@navikt/aksel",
|
||||
"@navikt/ds-icons"
|
||||
"@navikt/ds-icons",
|
||||
"@navikt/aksel-stylelint"
|
||||
]
|
||||
],
|
||||
"linked": [],
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @navikt/aksel-icons
|
||||
|
||||
## 3.4.2
|
||||
|
||||
## 3.4.1
|
||||
|
||||
## 3.4.0
|
||||
|
||||
## 3.3.1
|
||||
|
||||
## 3.3.0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/aksel-icons",
|
||||
"version": "3.3.1",
|
||||
"version": "3.4.2",
|
||||
"author": "Aksel | NAV",
|
||||
"homepage": "https://aksel.nav.no/ikoner",
|
||||
"repository": {
|
||||
@@ -53,7 +53,7 @@
|
||||
"scripts": {
|
||||
"create-icons": "svgr --silent --index-template config/index-template.js --out-dir src icons",
|
||||
"copy-util": "copyfiles util/* src",
|
||||
"copy-svg": "copyfiles -f icons/*.svg dist/svg/",
|
||||
"copy-svg": "copyfiles -f 'icons/*.svg' dist/svg/",
|
||||
"copy": "yarn copy-util && yarn copy-svg",
|
||||
"update-metadata": "node config/metadata.js",
|
||||
"build": "yarn copy && yarn create-icons && concurrently \"tsc\" \"tsc -p tsconfig.esm.json\" && node config/cleanTypes.js && yarn update-metadata",
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
/dist
|
||||
@@ -0,0 +1,19 @@
|
||||
# @navikt/aksel-stylelint
|
||||
|
||||
## 3.4.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2017](https://github.com/navikt/aksel/pull/2017) [`7615dbbb5`](https://github.com/navikt/aksel/commit/7615dbbb54c7c96e2252366188547b27b2ac1142) Thanks [@JulianNymark](https://github.com/JulianNymark)! - add missing dependency
|
||||
|
||||
## 3.4.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- :bug: Stylelint hotfix, inkluderer nå dist-mappe (kanskje..)
|
||||
|
||||
## 3.4.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#1973](https://github.com/navikt/aksel/pull/1973) [`61c411421`](https://github.com/navikt/aksel/commit/61c4114214841ec42f48e1abd0d72d2a42d265ab) Thanks [@JulianNymark](https://github.com/JulianNymark)! - add stylelint plugin
|
||||
@@ -0,0 +1,173 @@
|
||||
# Aksel stylelint rules & plugins
|
||||
|
||||
This stylelint plugin is useful when working with the [Aksel design system](https://aksel.nav.no/).
|
||||
|
||||
It is designed to be useful for both _internal_ and _external_ developers, so _everyone_ should install this 🙌.
|
||||
|
||||
> **Warning**
|
||||
> The version of this plugin **_MUST MATCH_** the version of the other design system packages used in your project for the linting to make sense!
|
||||
> Otherwise you are very likely to get _incorrect_ errors that tell you to use the wrong token names.
|
||||
|
||||
# Install
|
||||
|
||||
```bash
|
||||
yarn add -D @navikt/aksel-stylelint
|
||||
npm install -D @navikt/aksel-stylelint
|
||||
```
|
||||
|
||||
### How to configure
|
||||
|
||||
It should be sufficient for most cases to extend the recommended defaults.
|
||||
|
||||
```js
|
||||
"stylelint": {
|
||||
"extends": [
|
||||
...
|
||||
"@navikt/aksel-stylelint/recommended"
|
||||
],
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
## aksel/design-token-exists
|
||||
|
||||
Makes sure all referenced CSS-variables with prefix `--a-` or `--ac-` exists in Aksels token-collection. As a side-effect Aksel reserves these prefixes for its design-tokens.
|
||||
|
||||
❌ Incorrect:
|
||||
|
||||
```css
|
||||
html {
|
||||
--a-my-own-color-bg-hover: #f2f2f2;
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
background-color: var(--a-my-own-color-bg-hover);
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
}
|
||||
```
|
||||
|
||||
✅ Correct:
|
||||
|
||||
```css
|
||||
html {
|
||||
background-color: var(--custom-tag-surface-default);
|
||||
}
|
||||
```
|
||||
|
||||
## aksel/design-token-no-global-override
|
||||
|
||||
Makes sure you don't override global level tokens with `--a-`-prefix. Global/Semantic tokens are supposed to be used as is, and not overridden. That is unless you are theming your solution to match a different sub-brands or brands. In those cases we encourage to make all the changes in a single 'config'-file, then disable the rule for that file only.
|
||||
|
||||
❌ Incorrect:
|
||||
|
||||
```css
|
||||
div {
|
||||
--a-surface-default: #f2f2f2;
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
}
|
||||
```
|
||||
|
||||
✅ Correct:
|
||||
|
||||
```css
|
||||
div {
|
||||
background-color: var(--a-surface-default);
|
||||
}
|
||||
```
|
||||
|
||||
## aksel/design-token-no-component-reference
|
||||
|
||||
Makes sure you don't reference component level tokens with `--ac-`-prefix. Component level tokens are only supposed to be overridden, not referenced.
|
||||
This is since they are by default not defined, leading to unknown side-effects when referenced incorrectly.
|
||||
|
||||
❌ Incorrect:
|
||||
|
||||
```css
|
||||
html {
|
||||
stroke: var(--ac-button-loader-stroke);
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
}
|
||||
```
|
||||
|
||||
✅ Correct:
|
||||
|
||||
```css
|
||||
html {
|
||||
--ac-button-loader-stroke: lawngreen;
|
||||
}
|
||||
```
|
||||
|
||||
## aksel/no-internal-tokens
|
||||
|
||||
Disallows use or override of internal Aksel design tokens. Internal tokens are not supposed to be used outside the design system, and may be changed or removed without warning. Be aware that the rule simply checks the prefix of the token, and not if it actually exists in the design system. Even if it doesn't exist, using design system prefixes should be avoided.
|
||||
|
||||
❌ Incorrect:
|
||||
|
||||
```css
|
||||
a {
|
||||
--__ac-some-property: pink;
|
||||
} ^^^^^^^^^^^^^^^^^^^^
|
||||
```
|
||||
|
||||
```css
|
||||
a {
|
||||
color: var(--__ac-some-property);
|
||||
} ^^^^^^^^^^^^^^^^^^^^
|
||||
```
|
||||
|
||||
✅ Correct:
|
||||
|
||||
```css
|
||||
a {
|
||||
--some-property: pink;
|
||||
}
|
||||
```
|
||||
|
||||
```css
|
||||
a {
|
||||
color: var(--some-property);
|
||||
}
|
||||
```
|
||||
|
||||
## aksel/no-class-override
|
||||
|
||||
Warns when trying to override design system styling by using class selectors that starts with "navds-" or "navdsi-". Overriding styles in the design system is discouraged. We want to have consistent look and feel across applications. Even if it seems to work fine now, it might break on subsequent updates in the design system.
|
||||
|
||||
❌ Incorrect:
|
||||
|
||||
```css
|
||||
.navds-button {
|
||||
^^^^^^^^^^^^^
|
||||
}
|
||||
```
|
||||
|
||||
```css
|
||||
.some-class .navdsi-header {
|
||||
} ^^^^^^^^^^^^^^
|
||||
```
|
||||
|
||||
✅ Correct:
|
||||
|
||||
```css
|
||||
.some-class {
|
||||
}
|
||||
```
|
||||
|
||||
## aksel/no-deprecated-classes
|
||||
|
||||
Warns when you try to use deprecated class names.
|
||||
|
||||
❌ Incorrect:
|
||||
|
||||
```css
|
||||
.navdsi-deprecated-example {
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
}
|
||||
```
|
||||
|
||||
✅ Correct:
|
||||
|
||||
```css
|
||||
.guaranteed-not-deprecated {
|
||||
}
|
||||
```
|
||||
|
||||
🐛 Found a bug? https://github.com/navikt/aksel/issues
|
||||
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"name": "@navikt/aksel-stylelint",
|
||||
"version": "3.4.2",
|
||||
"author": "Aksel | NAV",
|
||||
"homepage": "https://aksel.nav.no/grunnleggende/kode/stylelint",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/navikt/aksel.git",
|
||||
"directory": "@navikt/aksel-stylelint"
|
||||
},
|
||||
"keywords": [
|
||||
"aksel",
|
||||
"stylelint",
|
||||
"config",
|
||||
"linting"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"license": "MIT",
|
||||
"main": "./dist/index.js",
|
||||
"exports": {
|
||||
"./recommended": "./dist/recommended.js"
|
||||
},
|
||||
"files": [
|
||||
"/dist"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "jest",
|
||||
"copy-internal-tokens": "node -e \"require('fs').copyFileSync('../internal/css/tokens.json','dist/internal-tokens.json')\"",
|
||||
"copy-css": "node -e \"require('fs').copyFileSync('../core/css/dist/index.css','dist/index.css')\"",
|
||||
"copy-tokens": "node -e \"require('fs').copyFileSync('../core/css/tokens.json','dist/tokens.json')\"",
|
||||
"copy": "yarn copy-internal-tokens && yarn copy-css && yarn copy-tokens",
|
||||
"build": "tsc -p . && concurrently \"yarn:copy-*\"",
|
||||
"watch:lint": "tsc --watch -p .",
|
||||
"dev": "yarn watch:lint"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@navikt/ds-css": "^3.4.2",
|
||||
"@navikt/ds-tokens": "^3.4.2",
|
||||
"@types/jest": "^29.0.0",
|
||||
"concurrently": "7.2.1",
|
||||
"copyfiles": "2.4.1",
|
||||
"jest": "^29.0.0",
|
||||
"jest-preset-stylelint": "^6.1.0",
|
||||
"postcss-selector-parser": "^6.0.13",
|
||||
"postcss-value-parser": "^4.2.0",
|
||||
"stylelint": "^14.8.5",
|
||||
"typescript": "^4.8.0"
|
||||
},
|
||||
"jest": {
|
||||
"preset": "jest-preset-stylelint",
|
||||
"testMatch": [
|
||||
"**/*.test.ts"
|
||||
],
|
||||
"transform": {
|
||||
"^.+\\.ts?$": "ts-jest"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
type DeprecatedList = { classes: string[]; message: string }[];
|
||||
|
||||
export const deprecations: DeprecatedList = [
|
||||
{
|
||||
classes: ["navdsi-deprecated-example", "navdsi-other-deprecated-example"],
|
||||
message: "Removed in vX.X.X, see documentation [link] for more information",
|
||||
},
|
||||
];
|
||||
@@ -0,0 +1,8 @@
|
||||
import { createPlugin } from "stylelint";
|
||||
import { rules } from "./rules";
|
||||
|
||||
const rulesPlugins = Object.keys(rules).map((ruleName) => {
|
||||
return createPlugin(`${ruleName}`, rules[ruleName]);
|
||||
});
|
||||
|
||||
export default rulesPlugins;
|
||||
@@ -0,0 +1,11 @@
|
||||
module.exports = {
|
||||
plugins: ["."],
|
||||
rules: {
|
||||
"aksel/design-token-exists": true,
|
||||
"aksel/no-internal-tokens": true,
|
||||
"aksel/no-class-override": [true, { severity: "warning" }],
|
||||
"aksel/no-deprecated-classes": true,
|
||||
"aksel/design-token-no-global-override": true,
|
||||
"aksel/design-token-no-component-reference": true,
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,94 @@
|
||||
import { getTestRule } from "jest-preset-stylelint";
|
||||
import rule, { messages } from ".";
|
||||
|
||||
getTestRule()({
|
||||
plugins: ["./dist/index.js"],
|
||||
ruleName: rule.ruleName,
|
||||
config: true,
|
||||
|
||||
accept: [
|
||||
{
|
||||
code: ".foo { --ac-accordion-header-bg-hover: 1px; --ac-header-bg: red; }",
|
||||
description: "existing '--ac-' tokens overridden",
|
||||
},
|
||||
{
|
||||
code: ".foo { --my-custom-color: var(--a-orange-800); }",
|
||||
description: "existing '--a-' token referenced",
|
||||
},
|
||||
],
|
||||
|
||||
reject: [
|
||||
{
|
||||
code: ".foo { --a-does-not-exist: 1px }",
|
||||
description: "attempt to override nonexistent '--a-' token",
|
||||
warnings: [
|
||||
{
|
||||
message: messages.propNotExist({ prop: "--a-does-not-exist" }),
|
||||
line: 1,
|
||||
endLine: 1,
|
||||
column: 8,
|
||||
endColumn: 26,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: ".foo \n { \n --ac-does-not-exist: 1px; \n }",
|
||||
description: "attempt to override nonexistent '--ac-' token",
|
||||
message: messages.propNotExist({ prop: "--ac-does-not-exist" }),
|
||||
line: 3,
|
||||
endLine: 3,
|
||||
column: 2,
|
||||
endColumn: 21,
|
||||
},
|
||||
|
||||
{
|
||||
code: ".foo { color: var(--a-bar) }",
|
||||
description: "attempt to use nonexistent token",
|
||||
message: messages.valueNotExist({ prop: "color" }, "--a-bar"),
|
||||
line: 1,
|
||||
endLine: 1,
|
||||
column: 19,
|
||||
endColumn: 26,
|
||||
},
|
||||
{
|
||||
code: ".foo { width: var(--ac-bar, --a-baz) }",
|
||||
description: "attempt to use two nonexistent tokens in one var()",
|
||||
warnings: [
|
||||
{
|
||||
message: messages.valueNotExist({ prop: "width" }, "--ac-bar"),
|
||||
line: 1,
|
||||
endLine: 1,
|
||||
column: 19,
|
||||
endColumn: 27,
|
||||
},
|
||||
{
|
||||
message: messages.valueNotExist({ prop: "width" }, "--a-baz"),
|
||||
line: 1,
|
||||
endLine: 1,
|
||||
column: 29,
|
||||
endColumn: 36,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: ".foo { padding: var(--a-bar) var(--a-baz); }",
|
||||
description: "attempt to use two nonexistent tokens as separate vars",
|
||||
warnings: [
|
||||
{
|
||||
message: messages.valueNotExist({ prop: "padding" }, "--a-bar"),
|
||||
line: 1,
|
||||
endLine: 1,
|
||||
column: 21,
|
||||
endColumn: 28,
|
||||
},
|
||||
{
|
||||
message: messages.valueNotExist({ prop: "padding" }, "--a-baz"),
|
||||
line: 1,
|
||||
endLine: 1,
|
||||
column: 34,
|
||||
endColumn: 41,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -0,0 +1,96 @@
|
||||
import stylelint from "stylelint";
|
||||
import valueParser from "postcss-value-parser";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { Node as PostCSSNode } from "postcss";
|
||||
|
||||
import { isCustomProperty, tokenExists } from "../../utils";
|
||||
|
||||
const packageJson = JSON.parse(
|
||||
readFileSync(`${__dirname}/../../../package.json`).toString()
|
||||
);
|
||||
|
||||
const ruleName = "aksel/design-token-exists";
|
||||
|
||||
const prefix_a = "--a-";
|
||||
const prefix_ac = "--ac-";
|
||||
export const controlledPrefixes = [prefix_a, prefix_ac];
|
||||
|
||||
const packageVersion = packageJson.version;
|
||||
|
||||
export const messages = stylelint.utils.ruleMessages(ruleName, {
|
||||
propNotExist: (node: any) =>
|
||||
`("${node.prop}") does not exist in the design system.\n\n` +
|
||||
`Property "${node.prop}" has a name that seems like it intends to override a design token by ` +
|
||||
`using one of the following prefixes [${controlledPrefixes}]. ` +
|
||||
`However, that token doesn"t seem to exist in the design system. ` +
|
||||
`\n\nVersion: ${packageVersion}`,
|
||||
valueNotExist: (node: any, invalidValues: string) =>
|
||||
`("${invalidValues}") does not exist in the design system.\n\n` +
|
||||
`Property "${node.prop}" has offending value "${invalidValues}", ` +
|
||||
`and the value seems like it intends to reference a design token by ` +
|
||||
`using one of the following prefixes [${controlledPrefixes}]. ` +
|
||||
`However, that token doesn't seem to exist in the design system. ` +
|
||||
`\n\nVersion: ${packageVersion}`,
|
||||
});
|
||||
|
||||
const checkDeclValue = (
|
||||
controlledPrefixes: string[],
|
||||
value: string,
|
||||
postcssResult: stylelint.PostcssResult,
|
||||
rootNode: PostCSSNode
|
||||
) => {
|
||||
valueParser(value).walk((node) => {
|
||||
if (
|
||||
node.type === "word" &&
|
||||
isCustomProperty(node.value) &&
|
||||
controlledPrefixes.some((prefix) => node.value.startsWith(prefix)) &&
|
||||
!tokenExists(controlledPrefixes, node.value)
|
||||
) {
|
||||
stylelint.utils.report({
|
||||
message: messages.valueNotExist(rootNode, node.value),
|
||||
node: rootNode,
|
||||
result: postcssResult,
|
||||
ruleName,
|
||||
word: node.value,
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const checkDeclProp = (
|
||||
controlledPrefixes: string[],
|
||||
prop: string,
|
||||
postcssResult: stylelint.PostcssResult,
|
||||
rootNode: PostCSSNode
|
||||
) => {
|
||||
if (
|
||||
isCustomProperty(prop) &&
|
||||
controlledPrefixes.some((prefix) => prop.startsWith(prefix)) &&
|
||||
!tokenExists(controlledPrefixes, prop)
|
||||
) {
|
||||
stylelint.utils.report({
|
||||
message: messages.propNotExist(rootNode),
|
||||
node: rootNode,
|
||||
result: postcssResult,
|
||||
ruleName,
|
||||
word: prop,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const ruleFunction: stylelint.Rule = () => {
|
||||
return (postcssRoot, postcssResult) => {
|
||||
postcssRoot.walkDecls((node) => {
|
||||
checkDeclValue(controlledPrefixes, node.value, postcssResult, node);
|
||||
checkDeclProp(controlledPrefixes, node.prop, postcssResult, node);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
ruleFunction.ruleName = ruleName;
|
||||
ruleFunction.messages = {};
|
||||
ruleFunction.meta = {
|
||||
url: `https://github.com/navikt/aksel/blob/main/%40navikt/aksel-stylelint/README.md#${ruleName}`,
|
||||
};
|
||||
|
||||
export default ruleFunction;
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
import { getTestRule } from "jest-preset-stylelint";
|
||||
import rule, { messages } from ".";
|
||||
|
||||
getTestRule()({
|
||||
plugins: ["./dist/index.js"],
|
||||
ruleName: rule.ruleName,
|
||||
config: true,
|
||||
|
||||
accept: [
|
||||
{
|
||||
code: ".foo { --ac-accordion-header-bg-hover: 1px; --ac-header-bg: red; }",
|
||||
description: "existing '--ac-' tokens overridden",
|
||||
},
|
||||
{
|
||||
code: ".foo { --my-custom-color: var(--a-orange-800); }",
|
||||
description: "existing '--a-' token referenced",
|
||||
},
|
||||
],
|
||||
|
||||
reject: [
|
||||
{
|
||||
code: ".foo { width: var(--ac-button-padding) }",
|
||||
description: "attempt to use '--ac-' token",
|
||||
message: messages.valueRefComponent(
|
||||
{ prop: "width" },
|
||||
"--ac-button-padding"
|
||||
),
|
||||
line: 1,
|
||||
endLine: 1,
|
||||
column: 19,
|
||||
endColumn: 38,
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -0,0 +1,60 @@
|
||||
import stylelint from "stylelint";
|
||||
import { Node as PostCSSNode } from "postcss";
|
||||
import valueParser from "postcss-value-parser";
|
||||
|
||||
import { getPackageVersion, isCustomProperty, tokenExists } from "../../utils";
|
||||
|
||||
const ruleName = "aksel/design-token-no-component-reference";
|
||||
const packageVersion = getPackageVersion();
|
||||
|
||||
const prefix_ac = "--ac-";
|
||||
|
||||
export const messages = stylelint.utils.ruleMessages(ruleName, {
|
||||
valueRefComponent: (node: any, invalidValue: string) =>
|
||||
`Referencing ("${prefix_ac}*") not allowed.\n\n` +
|
||||
`Property "${node.prop}" has offending value "${invalidValue}". ` +
|
||||
`The value references a component level token ("${prefix_ac}"). ` +
|
||||
`It is better to either reference a global level token ("--a-") or ` +
|
||||
`create a custom token instead. ` +
|
||||
`\n\nVersion: ${packageVersion}`,
|
||||
});
|
||||
|
||||
const checkDeclValue = (
|
||||
controlledPrefixes: string[],
|
||||
value: string,
|
||||
postcssResult: stylelint.PostcssResult,
|
||||
rootNode: PostCSSNode
|
||||
) => {
|
||||
valueParser(value).walk((node) => {
|
||||
if (
|
||||
node.type === "word" &&
|
||||
isCustomProperty(node.value) &&
|
||||
node.value.startsWith(prefix_ac) &&
|
||||
tokenExists(controlledPrefixes, node.value)
|
||||
) {
|
||||
stylelint.utils.report({
|
||||
message: messages.valueRefComponent(rootNode, node.value),
|
||||
node: rootNode,
|
||||
result: postcssResult,
|
||||
ruleName,
|
||||
word: node.value,
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const ruleFunction: stylelint.Rule = () => {
|
||||
return (postcssRoot, postcssResult) => {
|
||||
postcssRoot.walkDecls((node) => {
|
||||
checkDeclValue([prefix_ac], node.value, postcssResult, node);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
ruleFunction.ruleName = ruleName;
|
||||
ruleFunction.messages = {};
|
||||
ruleFunction.meta = {
|
||||
url: `https://github.com/navikt/aksel/blob/main/%40navikt/aksel-stylelint/README.md#${ruleName}`,
|
||||
};
|
||||
|
||||
export default ruleFunction;
|
||||
@@ -0,0 +1,44 @@
|
||||
import { getTestRule } from "jest-preset-stylelint";
|
||||
import rule, { messages } from ".";
|
||||
|
||||
getTestRule()({
|
||||
plugins: ["./dist/index.js"],
|
||||
ruleName: rule.ruleName,
|
||||
config: true,
|
||||
|
||||
accept: [
|
||||
{
|
||||
code: ".foo { --ac-accordion-header-bg-hover: 1px; --ac-header-bg: red; }",
|
||||
description: "existing '--ac-' tokens overridden",
|
||||
},
|
||||
{
|
||||
code: ".foo { --my-custom-color: var(--a-orange-800); }",
|
||||
description: "existing '--a-' token referenced",
|
||||
},
|
||||
],
|
||||
|
||||
reject: [
|
||||
{
|
||||
code: ".foo { --a-surface-action: 1px }",
|
||||
description: "existing '--a-' token overridden",
|
||||
message: messages.propOverrideGlobal({ prop: "--a-surface-action" }),
|
||||
line: 1,
|
||||
endLine: 1,
|
||||
column: 8,
|
||||
endColumn: 26,
|
||||
},
|
||||
{
|
||||
code: ".foo { --a-does-not-exist: 1px }",
|
||||
description: "attempt to override nonexistent '--a-' token",
|
||||
warnings: [
|
||||
{
|
||||
message: messages.propOverrideGlobal({ prop: "--a-does-not-exist" }),
|
||||
line: 1,
|
||||
endLine: 1,
|
||||
column: 8,
|
||||
endColumn: 26,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -0,0 +1,62 @@
|
||||
import stylelint from "stylelint";
|
||||
import { readFileSync } from "node:fs";
|
||||
|
||||
import { Node as PostCSSNode } from "postcss";
|
||||
import { isCustomProperty } from "../../utils";
|
||||
|
||||
const packageJson = JSON.parse(
|
||||
readFileSync(`${__dirname}/../../../package.json`).toString()
|
||||
);
|
||||
|
||||
const ruleName = "aksel/design-token-no-global-override";
|
||||
|
||||
const prefix_a = "--a-";
|
||||
|
||||
const packageVersion = packageJson.version;
|
||||
|
||||
export const messages = stylelint.utils.ruleMessages(ruleName, {
|
||||
propOverrideGlobal: (node: any) =>
|
||||
`Overriding ("${node.prop}*") not allowed.\n\n` +
|
||||
`Property "${node.prop}" tries to override a global level token ("${prefix_a}"), this is highly discouraged. ` +
|
||||
`It is better to override a component level token ("--ac-") or create a custom token instead. ` +
|
||||
`Overriding global tokens should only be done when creating custom global themes.` +
|
||||
`\n\nVersion: ${packageVersion}`,
|
||||
});
|
||||
|
||||
const checkDeclProp = (
|
||||
controlledPrefixes: string[],
|
||||
prop: string,
|
||||
postcssResult: stylelint.PostcssResult,
|
||||
rootNode: PostCSSNode
|
||||
) => {
|
||||
if (
|
||||
isCustomProperty(prop) &&
|
||||
controlledPrefixes.some((prefix) => prop.startsWith(prefix))
|
||||
) {
|
||||
if (prop.startsWith(prefix_a)) {
|
||||
stylelint.utils.report({
|
||||
message: messages.propOverrideGlobal(rootNode),
|
||||
node: rootNode,
|
||||
result: postcssResult,
|
||||
ruleName,
|
||||
word: prop,
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const ruleFunction: stylelint.Rule = () => {
|
||||
return (postcssRoot, postcssResult) => {
|
||||
postcssRoot.walkDecls((node) => {
|
||||
checkDeclProp([prefix_a], node.prop, postcssResult, node);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
ruleFunction.ruleName = ruleName;
|
||||
ruleFunction.messages = {};
|
||||
ruleFunction.meta = {
|
||||
url: `https://github.com/navikt/aksel/blob/main/%40navikt/aksel-stylelint/README.md#${ruleName}`,
|
||||
};
|
||||
|
||||
export default ruleFunction;
|
||||
@@ -0,0 +1,31 @@
|
||||
import { getTestRule } from "jest-preset-stylelint";
|
||||
import rule, { messages } from ".";
|
||||
|
||||
getTestRule()({
|
||||
plugins: ["./dist/index.js"],
|
||||
ruleName: rule.ruleName,
|
||||
config: true,
|
||||
|
||||
accept: [{ code: ".foo-navds-bar {}", description: "allowed class name" }],
|
||||
|
||||
reject: [
|
||||
{
|
||||
code: ".foo, \n .navds-button \n .bar {}",
|
||||
description: "selector with disallowed class name .navds-*",
|
||||
message: messages.unexpected("navds-button"),
|
||||
line: 2,
|
||||
endLine: 2,
|
||||
column: 3,
|
||||
endColumn: 15,
|
||||
},
|
||||
{
|
||||
code: ".foo .navdsi-button \n .bar {}",
|
||||
description: "selector with disallowed class name .navdsi-*",
|
||||
message: messages.unexpected("navdsi-button"),
|
||||
line: 1,
|
||||
endLine: 1,
|
||||
column: 7,
|
||||
endColumn: 20,
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -0,0 +1,42 @@
|
||||
import stylelint from "stylelint";
|
||||
import selectorParser from "postcss-selector-parser";
|
||||
|
||||
const ruleName = "aksel/no-class-override";
|
||||
const url =
|
||||
"https://github.com/navikt/aksel/blob/main/%40navikt/aksel-stylelint/README.md#aksel/no-class-override";
|
||||
const prefixes = ["navds-", "navdsi-"];
|
||||
|
||||
export const messages = stylelint.utils.ruleMessages(ruleName, {
|
||||
unexpected: (value) =>
|
||||
`("${value}") not allowed.\n\n` +
|
||||
`"${value}" looks like a class name used in the design system, ` +
|
||||
`because it starts with "${prefixes.join('" or "')}". ` +
|
||||
"It is not recommended to override the styling in the design system.",
|
||||
});
|
||||
|
||||
const ruleFunction: stylelint.Rule = () => {
|
||||
return (postcssRoot, postcssResult) => {
|
||||
postcssRoot.walkRules((node) => {
|
||||
selectorParser((selectors) => {
|
||||
selectors.walkClasses((className) => {
|
||||
if (!prefixes.some((prefix) => className.value.startsWith(prefix))) {
|
||||
return;
|
||||
}
|
||||
stylelint.utils.report({
|
||||
message: messages.unexpected(className.value),
|
||||
node,
|
||||
result: postcssResult,
|
||||
ruleName,
|
||||
word: className.value,
|
||||
});
|
||||
});
|
||||
}).processSync(node.selector);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
ruleFunction.ruleName = ruleName;
|
||||
ruleFunction.messages = messages;
|
||||
ruleFunction.meta = { url };
|
||||
|
||||
export default ruleFunction;
|
||||
@@ -0,0 +1,44 @@
|
||||
import { getTestRule } from "jest-preset-stylelint";
|
||||
import rule, { messages } from ".";
|
||||
import { deprecations } from "../../deprecations";
|
||||
|
||||
getTestRule()({
|
||||
plugins: ["./dist/index.js"],
|
||||
ruleName: rule.ruleName,
|
||||
config: true,
|
||||
|
||||
accept: [
|
||||
{
|
||||
code: ".navds-foo, navdsi-bar, .baz {}",
|
||||
description: "allowed class names",
|
||||
// Allowed because this rule only checks deprecated class names. See also aksel/no-class-override.
|
||||
},
|
||||
],
|
||||
|
||||
reject: [
|
||||
{
|
||||
code: ".foo, \n .navdsi-deprecated-example \n .bar {}",
|
||||
description: "selector with deprecated class name 1",
|
||||
message: messages.unexpected(
|
||||
"navdsi-deprecated-example",
|
||||
deprecations[0].message
|
||||
),
|
||||
line: 2,
|
||||
endLine: 2,
|
||||
column: 3,
|
||||
endColumn: 28,
|
||||
},
|
||||
{
|
||||
code: ".foo .navdsi-other-deprecated-example \n .bar {}",
|
||||
description: "selector with deprecated class name 2",
|
||||
message: messages.unexpected(
|
||||
"navdsi-other-deprecated-example",
|
||||
deprecations[0].message
|
||||
),
|
||||
line: 1,
|
||||
endLine: 1,
|
||||
column: 7,
|
||||
endColumn: 38,
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -0,0 +1,44 @@
|
||||
import stylelint from "stylelint";
|
||||
import selectorParser from "postcss-selector-parser";
|
||||
import { deprecations } from "../../deprecations";
|
||||
|
||||
const ruleName = "aksel/no-deprecated-classes";
|
||||
const url =
|
||||
"https://github.com/navikt/aksel/blob/main/%40navikt/aksel-stylelint/README.md#aksel/no-deprecated-classes";
|
||||
|
||||
export const messages = stylelint.utils.ruleMessages(ruleName, {
|
||||
unexpected: (value, secondaryOption) =>
|
||||
`Class "${value}" is deprecated. ` + secondaryOption,
|
||||
});
|
||||
|
||||
const ruleFunction: stylelint.Rule = () => {
|
||||
return (postcssRoot, postcssResult) => {
|
||||
postcssRoot.walkRules((node) => {
|
||||
selectorParser((selectors) => {
|
||||
selectors.walkClasses((className) => {
|
||||
for (const deprecation of deprecations) {
|
||||
if (!deprecation.classes.includes(className.value)) {
|
||||
return;
|
||||
}
|
||||
stylelint.utils.report({
|
||||
message: messages.unexpected(
|
||||
className.value,
|
||||
deprecation.message
|
||||
),
|
||||
node,
|
||||
result: postcssResult,
|
||||
ruleName,
|
||||
word: className.value,
|
||||
});
|
||||
}
|
||||
});
|
||||
}).processSync(node.selector);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
ruleFunction.ruleName = ruleName;
|
||||
ruleFunction.messages = messages;
|
||||
ruleFunction.meta = { url };
|
||||
|
||||
export default ruleFunction;
|
||||
@@ -0,0 +1,80 @@
|
||||
import { getTestRule } from "jest-preset-stylelint";
|
||||
import rule, { messages } from ".";
|
||||
|
||||
getTestRule()({
|
||||
plugins: ["./dist/index.js"],
|
||||
ruleName: rule.ruleName,
|
||||
config: true,
|
||||
|
||||
accept: [
|
||||
{
|
||||
code: ".foo { --bar--__ac-baz: 1px }",
|
||||
description: "non-internal token defined",
|
||||
},
|
||||
{
|
||||
code: ".foo { font-size: var(--bar--__ac-baz) }",
|
||||
description: "non-internal token used",
|
||||
},
|
||||
],
|
||||
|
||||
reject: [
|
||||
{
|
||||
code: ".foo { --__ac-bar: 1px; }",
|
||||
description: "internal token overridden",
|
||||
message: messages.tokenOverridden("--__ac-bar"),
|
||||
line: 1,
|
||||
endLine: 1,
|
||||
column: 8,
|
||||
endColumn: 24,
|
||||
},
|
||||
{
|
||||
code: ".foo { color: var(--__ac-bar) }",
|
||||
description: "one internal token used",
|
||||
message: messages.tokenUsed("--__ac-bar", "color"),
|
||||
line: 1,
|
||||
endLine: 1,
|
||||
column: 19,
|
||||
endColumn: 29,
|
||||
},
|
||||
{
|
||||
code: ".foo { width: var(--__ac-bar, --__ac-baz) }",
|
||||
description: "two internal tokens used in one var()",
|
||||
warnings: [
|
||||
{
|
||||
message: messages.tokenUsed("--__ac-bar", "width"),
|
||||
line: 1,
|
||||
endLine: 1,
|
||||
column: 19,
|
||||
endColumn: 29,
|
||||
},
|
||||
{
|
||||
message: messages.tokenUsed("--__ac-baz", "width"),
|
||||
line: 1,
|
||||
endLine: 1,
|
||||
column: 31,
|
||||
endColumn: 41,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
code: ".foo { padding: var(--__ac-bar) var(--__ac-baz); }",
|
||||
description: "two internal tokens used as separate vars",
|
||||
warnings: [
|
||||
{
|
||||
message: messages.tokenUsed("--__ac-bar", "padding"),
|
||||
line: 1,
|
||||
endLine: 1,
|
||||
column: 21,
|
||||
endColumn: 31,
|
||||
},
|
||||
{
|
||||
message: messages.tokenUsed("--__ac-baz", "padding"),
|
||||
line: 1,
|
||||
endLine: 1,
|
||||
column: 37,
|
||||
endColumn: 47,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
@@ -0,0 +1,62 @@
|
||||
import stylelint from "stylelint";
|
||||
import valueParser from "postcss-value-parser";
|
||||
|
||||
const ruleName = "aksel/no-internal-tokens";
|
||||
const url =
|
||||
"https://github.com/navikt/aksel/blob/main/%40navikt/aksel-stylelint/README.md#aksel/no-internal-tokens";
|
||||
const prefix = "--__ac-";
|
||||
|
||||
export const messages = stylelint.utils.ruleMessages(ruleName, {
|
||||
tokenUsed: (token, prop) =>
|
||||
`("${token}") not allowed.\n\n` +
|
||||
`"${token}" (inside decleration "${prop}") looks like an internal design token, ` +
|
||||
`because it starts with "${prefix}". Internal tokens should not be used outside the design system.`,
|
||||
tokenOverridden: (token) =>
|
||||
`("${token}") not allowed.\n\n` +
|
||||
`"${token}" looks like an internal design token, because it starts with "${prefix}". ` +
|
||||
`Internal tokens should not be overridden.`,
|
||||
});
|
||||
|
||||
const getInternalTokensUsed = (value: string) => {
|
||||
const invalidValues: string[] = [];
|
||||
|
||||
valueParser(value).walk((node) => {
|
||||
if (node.type === "word" && node.value.startsWith(prefix)) {
|
||||
invalidValues.push(node.value);
|
||||
}
|
||||
});
|
||||
|
||||
return invalidValues;
|
||||
};
|
||||
|
||||
const ruleFunction: stylelint.Rule = () => {
|
||||
return (postcssRoot, postcssResult) => {
|
||||
postcssRoot.walkDecls((node) => {
|
||||
getInternalTokensUsed(node.value).forEach((token) => {
|
||||
stylelint.utils.report({
|
||||
message: messages.tokenUsed(token, node.prop),
|
||||
node,
|
||||
result: postcssResult,
|
||||
ruleName,
|
||||
word: token,
|
||||
});
|
||||
});
|
||||
|
||||
const isTokenOverride = node.prop.startsWith(prefix);
|
||||
if (isTokenOverride) {
|
||||
stylelint.utils.report({
|
||||
message: messages.tokenOverridden(node.prop),
|
||||
node,
|
||||
result: postcssResult,
|
||||
ruleName,
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
ruleFunction.ruleName = ruleName;
|
||||
ruleFunction.messages = {};
|
||||
ruleFunction.meta = { url };
|
||||
|
||||
export default ruleFunction;
|
||||
@@ -0,0 +1,16 @@
|
||||
import { Rule } from "stylelint";
|
||||
import designTokenExists from "./aksel-design-token-exists";
|
||||
import internalTokens from "./aksel-no-internal-tokens";
|
||||
import classOverride from "./aksel-no-class-override";
|
||||
import deprecatedClasses from "./aksel-no-deprecated-classes";
|
||||
import noGlobalOverride from "./aksel-design-token-no-global-override";
|
||||
import noComponentReference from "./aksel-design-token-no-component-reference";
|
||||
|
||||
export const rules: Record<string, Rule> = {
|
||||
"aksel/design-token-exists": designTokenExists,
|
||||
"aksel/design-token-no-global-override": noGlobalOverride,
|
||||
"aksel/design-token-no-component-reference": noComponentReference,
|
||||
"aksel/no-internal-tokens": internalTokens,
|
||||
"aksel/no-class-override": classOverride,
|
||||
"aksel/no-deprecated-classes": deprecatedClasses,
|
||||
};
|
||||
@@ -0,0 +1,138 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import valueParser from "postcss-value-parser";
|
||||
|
||||
export const isCustomProperty = (property) => {
|
||||
return property.startsWith("--");
|
||||
};
|
||||
|
||||
export const matchesStringOrRegExp = (input, comparison) => {
|
||||
if (!Array.isArray(input)) {
|
||||
return testAgainstStringOrRegExpOrArray(input, comparison);
|
||||
}
|
||||
|
||||
for (const inputItem of input) {
|
||||
const testResult = testAgainstStringOrRegExpOrArray(inputItem, comparison);
|
||||
|
||||
if (testResult) {
|
||||
return testResult;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
export const testAgainstStringOrRegExpOrArray = (value, comparison) => {
|
||||
if (!Array.isArray(comparison)) {
|
||||
return testAgainstStringOrRegExp(value, comparison);
|
||||
}
|
||||
|
||||
for (const comparisonItem of comparison) {
|
||||
const testResult = testAgainstStringOrRegExp(value, comparisonItem);
|
||||
|
||||
if (testResult) {
|
||||
return testResult;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
export const testAgainstStringOrRegExp = (value, comparison) => {
|
||||
// If it's a RegExp, test directly
|
||||
if (comparison instanceof RegExp) {
|
||||
return comparison.test(value)
|
||||
? { match: value, pattern: comparison }
|
||||
: false;
|
||||
}
|
||||
|
||||
// Check if it's RegExp in a string
|
||||
const firstComparisonChar = comparison[0];
|
||||
const lastComparisonChar = comparison[comparison.length - 1];
|
||||
const secondToLastComparisonChar = comparison[comparison.length - 2];
|
||||
|
||||
const comparisonIsRegex =
|
||||
firstComparisonChar === "/" &&
|
||||
(lastComparisonChar === "/" ||
|
||||
(secondToLastComparisonChar === "/" && lastComparisonChar === "i"));
|
||||
|
||||
const hasCaseInsensitiveFlag =
|
||||
comparisonIsRegex && lastComparisonChar === "i";
|
||||
|
||||
// If so, create a new RegExp from it
|
||||
if (comparisonIsRegex) {
|
||||
const valueMatches = hasCaseInsensitiveFlag
|
||||
? new RegExp(comparison.slice(1, -2), "i").test(value)
|
||||
: new RegExp(comparison.slice(1, -1)).test(value);
|
||||
|
||||
return valueMatches ? { match: value, pattern: comparison } : false;
|
||||
}
|
||||
|
||||
// Otherwise, it's a string. Do a strict comparison
|
||||
return value === comparison ? { match: value, pattern: comparison } : false;
|
||||
};
|
||||
|
||||
export const vendorUnprefixed = (prop) => {
|
||||
return prop.replace(/^-\w+-/, "");
|
||||
};
|
||||
|
||||
export const flattenObject = (obj) => {
|
||||
const flattened = Object.keys(obj).reduce((acc, key) => {
|
||||
if (typeof obj[key] === "string") {
|
||||
acc.push(key);
|
||||
} else {
|
||||
acc.push(flattenObject(obj[key]));
|
||||
}
|
||||
return acc;
|
||||
}, []);
|
||||
return flattened.flat();
|
||||
};
|
||||
|
||||
const tokenCSSFile = "./index.css";
|
||||
const tokenJsonFile = "./tokens.json";
|
||||
const internalTokensJSONFile = "./internal-tokens.json";
|
||||
|
||||
let allowedTokenNames = [];
|
||||
|
||||
export const addTokens = (
|
||||
tokenJSONFile: string,
|
||||
allowedTokenNames: string[]
|
||||
) => {
|
||||
const jsonFileBuffer = readFileSync(`${__dirname}/${tokenJSONFile}`);
|
||||
const fileString = jsonFileBuffer.toString();
|
||||
const flattened = flattenObject(JSON.parse(fileString));
|
||||
flattened.forEach((token) => allowedTokenNames.push(token));
|
||||
};
|
||||
|
||||
export const tokenExists = (
|
||||
controlledPrefixes: string[],
|
||||
inputToken: string
|
||||
) => {
|
||||
// "singleton" if statement (attempt at caching file parsing)
|
||||
if (!allowedTokenNames.length) {
|
||||
const cssFileBuffer = readFileSync(`${__dirname}/${tokenCSSFile}`);
|
||||
const cssFileString = cssFileBuffer.toString();
|
||||
|
||||
valueParser(cssFileString).walk((node) => {
|
||||
if (
|
||||
node.type === "word" &&
|
||||
isCustomProperty(node.value) &&
|
||||
controlledPrefixes.some((prefix) => node.value.startsWith(prefix))
|
||||
) {
|
||||
allowedTokenNames.push(node.value);
|
||||
}
|
||||
});
|
||||
|
||||
addTokens(tokenJsonFile, allowedTokenNames);
|
||||
addTokens(internalTokensJSONFile, allowedTokenNames);
|
||||
}
|
||||
|
||||
return allowedTokenNames.includes(inputToken);
|
||||
};
|
||||
|
||||
const packageJson = JSON.parse(
|
||||
readFileSync(`${__dirname}/../package.json`).toString()
|
||||
);
|
||||
|
||||
export const getPackageVersion = () => {
|
||||
return packageJson.version;
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "CommonJS",
|
||||
"sourceMap": false,
|
||||
"esModuleInterop": true,
|
||||
"target": "es2020",
|
||||
"preserveWatchOutput": true,
|
||||
"declaration": false,
|
||||
"types": ["node", "jest", "@types/jest"],
|
||||
"outDir": "dist",
|
||||
"rootDir": "./src",
|
||||
"resolveJsonModule": true,
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": ["**/*.ts"],
|
||||
"exclude": ["node_modules", "dist", "**/tests/**"]
|
||||
}
|
||||
@@ -1,5 +1,26 @@
|
||||
# @navikt/aksel
|
||||
|
||||
## 3.4.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-css@3.4.2
|
||||
|
||||
## 3.4.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-css@3.4.1
|
||||
|
||||
## 3.4.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b958d41a2`](https://github.com/navikt/aksel/commit/b958d41a20c66327658514fcf24ae20893c9531a)]:
|
||||
- @navikt/ds-css@3.4.0
|
||||
|
||||
## 3.3.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/aksel",
|
||||
"version": "3.3.1",
|
||||
"version": "3.4.2",
|
||||
"description": "Aksel command line interface. Handles css-imports, codemods and more",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"license": "MIT",
|
||||
@@ -29,7 +29,7 @@
|
||||
},
|
||||
"homepage": "https://aksel.nav.no/grunnleggende/kode/kommandolinje",
|
||||
"dependencies": {
|
||||
"@navikt/ds-css": "3.3.1",
|
||||
"@navikt/ds-css": "3.4.2",
|
||||
"axios": "1.3.6",
|
||||
"chalk": "4.1.0",
|
||||
"clipboardy": "^2.3.0",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { getLineTerminator } from "../../../utils/lineterminator";
|
||||
import renameProps from "../../../utils/rename-props";
|
||||
|
||||
/**
|
||||
@@ -64,5 +65,5 @@ export default function transformer(file, api, options) {
|
||||
});
|
||||
}
|
||||
|
||||
return root.toSource(options.printOptions);
|
||||
return root.toSource(getLineTerminator(file.source));
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
import { getLineTerminator } from "../../../utils/lineterminator";
|
||||
|
||||
/**
|
||||
* @param {import('jscodeshift').FileInfo} file
|
||||
* @param {import('jscodeshift').API} api
|
||||
@@ -79,5 +81,5 @@ export default function transformer(file, api, options) {
|
||||
});
|
||||
}
|
||||
|
||||
return root.toSource(options.printOptions);
|
||||
return root.toSource(getLineTerminator(file.source));
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import { getLineTerminator } from "../../../utils/lineterminator";
|
||||
import renameProps from "../../../utils/rename-props";
|
||||
|
||||
/**
|
||||
@@ -79,5 +80,5 @@ export default function transformer(file, api, options) {
|
||||
});
|
||||
}
|
||||
|
||||
return root.toSource(options.printOptions);
|
||||
return root.toSource(getLineTerminator(file.source));
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
} from "../../../utils/imports";
|
||||
import { translateToken } from "../../../utils/translate-token";
|
||||
import { tokens } from "../../../tokens-map.mjs";
|
||||
import { getLineTerminator } from "../../../utils/lineterminator";
|
||||
|
||||
/**
|
||||
* @param {import('jscodeshift').FileInfo} file
|
||||
@@ -55,7 +56,7 @@ export default function transformer(file: JSCodeshift, api) {
|
||||
"@navikt/ds-tokens/dist/tokens"
|
||||
);
|
||||
|
||||
let code = root.toSource();
|
||||
let code = root.toSource(getLineTerminator(file.source));
|
||||
|
||||
const rgx = new RegExp("(" + localName + ")", "gm");
|
||||
code = code.replace(rgx, out);
|
||||
@@ -63,5 +64,5 @@ export default function transformer(file: JSCodeshift, api) {
|
||||
}
|
||||
});
|
||||
|
||||
return root.toSource();
|
||||
return root.toSource(getLineTerminator(file.source));
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import chalk from "chalk";
|
||||
import moveAndRenameImport from "../../../utils/moveAndRenameImport";
|
||||
import removePropsFromComponent from "../../../utils/removeProps";
|
||||
import { getLineTerminator } from "../../../utils/lineterminator";
|
||||
|
||||
/**
|
||||
* @param {import('jscodeshift').FileInfo} file
|
||||
@@ -25,7 +26,7 @@ export default function transformer(file, api, options, ...rest) {
|
||||
});
|
||||
|
||||
if (localName === null) {
|
||||
return root.toSource(options.printOptions);
|
||||
return root.toSource(getLineTerminator(file.source));
|
||||
}
|
||||
|
||||
/* Finds and replaces import from CopyToClipboard -> CopyButton */
|
||||
@@ -85,5 +86,5 @@ export default function transformer(file, api, options, ...rest) {
|
||||
});
|
||||
}
|
||||
|
||||
return root.toSource(options.printOptions);
|
||||
return root.toSource(getLineTerminator(file.source));
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export const getLineTerminator = (source: string) => ({
|
||||
lineTerminator: source.includes("\r\n") ? "\r\n" : "\n",
|
||||
});
|
||||
@@ -1,5 +1,11 @@
|
||||
# @navikt/ds-codemod
|
||||
|
||||
## 3.4.2
|
||||
|
||||
## 3.4.1
|
||||
|
||||
## 3.4.0
|
||||
|
||||
## 3.3.1
|
||||
|
||||
## 3.3.0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-codemod",
|
||||
"version": "3.3.1",
|
||||
"version": "3.4.2",
|
||||
"description": "Aksel codemods for NAVs designsystem",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"license": "MIT",
|
||||
@@ -44,7 +44,7 @@
|
||||
"jscodeshift-add-imports": "1.0.10",
|
||||
"lodash": "4.17.21",
|
||||
"meow": "7.0.1",
|
||||
"prettier": "2.7.1"
|
||||
"prettier": "2.8.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/preset-env": "^7.0.0",
|
||||
|
||||
@@ -40,8 +40,8 @@
|
||||
"build-pict": "svgr --silent --index-template index-template.js --out-dir src/pictograms pictograms"
|
||||
},
|
||||
"dependencies": {
|
||||
"@navikt/ds-icons": "^3.3.1",
|
||||
"@navikt/ds-react": "^3.3.1",
|
||||
"@navikt/ds-icons": "^3.4.2",
|
||||
"@navikt/ds-react": "^3.4.2",
|
||||
"clsx": "^1.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
# @navikt/ds-css
|
||||
|
||||
## 3.4.2
|
||||
|
||||
## 3.4.1
|
||||
|
||||
## 3.4.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#2010](https://github.com/navikt/aksel/pull/2010) [`b958d41a2`](https://github.com/navikt/aksel/commit/b958d41a20c66327658514fcf24ae20893c9531a) Thanks [@HalvorHaugan](https://github.com/HalvorHaugan)! - Ny variant "moderate" i Tag
|
||||
|
||||
## 3.3.1
|
||||
|
||||
## 3.3.0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-css",
|
||||
"version": "3.3.1",
|
||||
"version": "3.4.2",
|
||||
"description": "CSS for NAV Designsystem",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"keywords": [
|
||||
@@ -27,7 +27,7 @@
|
||||
"css:get-version": "node config/get-version.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@navikt/ds-tokens": "^3.3.1",
|
||||
"@navikt/ds-tokens": "^3.4.2",
|
||||
"cssnano": "6.0.0",
|
||||
"fast-glob": "3.2.11",
|
||||
"lodash": "4.17.21",
|
||||
|
||||
@@ -31,6 +31,12 @@
|
||||
color: var(--ac-tag-error-filled-text, var(--a-text-on-danger));
|
||||
}
|
||||
|
||||
.navds-tag--error-moderate {
|
||||
border-color: transparent;
|
||||
background-color: var(--ac-tag-error-moderate-bg, var(--a-surface-danger-moderate));
|
||||
color: var(--ac-tag-error-moderate-text, var(--a-text-default));
|
||||
}
|
||||
|
||||
.navds-tag--success {
|
||||
border-color: var(--ac-tag-success-border, var(--a-border-success));
|
||||
background-color: var(--ac-tag-success-bg, var(--a-surface-success-subtle));
|
||||
@@ -43,6 +49,12 @@
|
||||
color: var(--ac-tag-success-filled-text, var(--a-text-on-success));
|
||||
}
|
||||
|
||||
.navds-tag--success-moderate {
|
||||
border-color: transparent;
|
||||
background-color: var(--ac-tag-success-moderate-bg, var(--a-surface-success-moderate));
|
||||
color: var(--ac-tag-success-moderate-text, var(--a-text-default));
|
||||
}
|
||||
|
||||
.navds-tag--warning {
|
||||
border-color: var(--ac-tag-warning-border, var(--a-border-warning));
|
||||
background-color: var(--ac-tag-warning-bg, var(--a-surface-warning-subtle));
|
||||
@@ -55,6 +67,12 @@
|
||||
color: var(--ac-tag-warning-filled-text, var(--a-text-on-warning));
|
||||
}
|
||||
|
||||
.navds-tag--warning-moderate {
|
||||
border-color: transparent;
|
||||
background-color: var(--ac-tag-warning-moderate-bg, var(--a-surface-warning-moderate));
|
||||
color: var(--ac-tag-warning-moderate-text, var(--a-text-default));
|
||||
}
|
||||
|
||||
.navds-tag--info {
|
||||
border-color: var(--ac-tag-info-border, var(--a-border-info));
|
||||
background-color: var(--ac-tag-info-bg, var(--a-surface-info-subtle));
|
||||
@@ -67,6 +85,12 @@
|
||||
color: var(--ac-tag-info-filled-text, var(--a-text-on-info));
|
||||
}
|
||||
|
||||
.navds-tag--info-moderate {
|
||||
border-color: transparent;
|
||||
background-color: var(--ac-tag-info-moderate-bg, var(--a-surface-info-moderate));
|
||||
color: var(--ac-tag-info-moderate-text, var(--a-text-default));
|
||||
}
|
||||
|
||||
.navds-tag--neutral {
|
||||
border-color: var(--ac-tag-neutral-border, var(--a-border-default));
|
||||
background-color: var(--ac-tag-neutral-bg, var(--a-surface-neutral-subtle));
|
||||
@@ -79,6 +103,12 @@
|
||||
color: var(--ac-tag-neutral-filled-text, var(--a-text-on-neutral));
|
||||
}
|
||||
|
||||
.navds-tag--neutral-moderate {
|
||||
border-color: transparent;
|
||||
background-color: var(--ac-tag-neutral-moderate-bg, var(--a-surface-neutral-moderate));
|
||||
color: var(--ac-tag-neutral-moderate-text, var(--a-text-default));
|
||||
}
|
||||
|
||||
.navds-tag--alt1 {
|
||||
border-color: var(--ac-tag-alt-1-border, var(--a-border-alt-1));
|
||||
background-color: var(--ac-tag-alt-1-bg, var(--a-surface-alt-1-subtle));
|
||||
@@ -91,6 +121,12 @@
|
||||
color: var(--ac-tag-alt-1-filled-text, var(--a-text-on-alt-1));
|
||||
}
|
||||
|
||||
.navds-tag--alt1-moderate {
|
||||
border-color: transparent;
|
||||
background-color: var(--ac-tag-alt-1-moderate-bg, var(--a-surface-alt-1-moderate));
|
||||
color: var(--ac-tag-alt-1-moderate-text, var(--a-text-default));
|
||||
}
|
||||
|
||||
.navds-tag--alt2 {
|
||||
border-color: var(--ac-tag-alt-2-border, var(--a-border-alt-2));
|
||||
background-color: var(--ac-tag-alt-2-bg, var(--a-surface-alt-2-subtle));
|
||||
@@ -103,6 +139,12 @@
|
||||
color: var(--ac-tag-alt-2-filled-text, var(--a-text-on-alt-2));
|
||||
}
|
||||
|
||||
.navds-tag--alt2-moderate {
|
||||
border-color: transparent;
|
||||
background-color: var(--ac-tag-alt-2-moderate-bg, var(--a-surface-alt-2-moderate));
|
||||
color: var(--ac-tag-alt-2-moderate-text, var(--a-text-default));
|
||||
}
|
||||
|
||||
.navds-tag--alt3 {
|
||||
border-color: var(--ac-tag-alt-3-border, var(--a-border-alt-3));
|
||||
background-color: var(--ac-tag-alt-3-bg, var(--a-surface-alt-3-subtle));
|
||||
@@ -114,3 +156,9 @@
|
||||
background-color: var(--ac-tag-alt-3-filled-bg, var(--a-surface-alt-3));
|
||||
color: var(--ac-tag-alt-3-filled-text, var(--a-text-on-alt-3));
|
||||
}
|
||||
|
||||
.navds-tag--alt3-moderate {
|
||||
border-color: transparent;
|
||||
background-color: var(--ac-tag-alt-3-moderate-bg, var(--a-surface-alt-3-moderate));
|
||||
color: var(--ac-tag-alt-3-moderate-text, var(--a-text-default));
|
||||
}
|
||||
@@ -251,41 +251,57 @@
|
||||
"--ac-tag-error-text": "--a-text-default",
|
||||
"--ac-tag-error-filled-bg": "--a-surface-danger",
|
||||
"--ac-tag-error-filled-text": "--a-text-on-danger",
|
||||
"--ac-tag-error-moderate-bg": "--a-surface-danger-moderate",
|
||||
"--ac-tag-error-moderate-text": "--a-text-default",
|
||||
"--ac-tag-success-border": "--a-border-success",
|
||||
"--ac-tag-success-bg": "--a-surface-success-subtle",
|
||||
"--ac-tag-success-text": "--a-text-default",
|
||||
"--ac-tag-success-filled-bg": "--a-surface-success",
|
||||
"--ac-tag-success-filled-text": "--a-text-on-success",
|
||||
"--ac-tag-success-moderate-bg": "--a-surface-success-moderate",
|
||||
"--ac-tag-success-moderate-text": "--a-text-default",
|
||||
"--ac-tag-warning-border": "--a-border-warning",
|
||||
"--ac-tag-warning-bg": "--a-surface-warning-subtle",
|
||||
"--ac-tag-warning-text": "--a-text-default",
|
||||
"--ac-tag-warning-filled-bg": "--a-surface-warning",
|
||||
"--ac-tag-warning-filled-text": "--a-text-on-warning",
|
||||
"--ac-tag-warning-moderate-bg": "--a-surface-warning-moderate",
|
||||
"--ac-tag-warning-moderate-text": "--a-text-default",
|
||||
"--ac-tag-info-border": "--a-border-info",
|
||||
"--ac-tag-info-bg": "--a-surface-info-subtle",
|
||||
"--ac-tag-info-text": "--a-text-default",
|
||||
"--ac-tag-info-filled-bg": "--a-surface-info",
|
||||
"--ac-tag-info-filled-text": "--a-text-on-info",
|
||||
"--ac-tag-info-moderate-bg": "--a-surface-info-moderate",
|
||||
"--ac-tag-info-moderate-text": "--a-text-default",
|
||||
"--ac-tag-neutral-border": "--a-border-default",
|
||||
"--ac-tag-neutral-bg": "--a-surface-neutral-subtle",
|
||||
"--ac-tag-neutral-text": "--a-text-default",
|
||||
"--ac-tag-neutral-filled-bg": "--a-surface-neutral",
|
||||
"--ac-tag-neutral-filled-text": "--a-text-on-neutral",
|
||||
"--ac-tag-neutral-moderate-bg": "--a-surface-neutral-moderate",
|
||||
"--ac-tag-neutral-moderate-text": "--a-text-default",
|
||||
"--ac-tag-alt-1-border": "--a-border-alt-1",
|
||||
"--ac-tag-alt-1-bg": "--a-surface-alt-1-subtle",
|
||||
"--ac-tag-alt-1-text": "--a-text-default",
|
||||
"--ac-tag-alt-1-filled-bg": "--a-surface-alt-1",
|
||||
"--ac-tag-alt-1-filled-text": "--a-text-on-alt-1",
|
||||
"--ac-tag-alt-1-moderate-bg": "--a-surface-alt-1-moderate",
|
||||
"--ac-tag-alt-1-moderate-text": "--a-text-default",
|
||||
"--ac-tag-alt-2-border": "--a-border-alt-2",
|
||||
"--ac-tag-alt-2-bg": "--a-surface-alt-2-subtle",
|
||||
"--ac-tag-alt-2-text": "--a-text-default",
|
||||
"--ac-tag-alt-2-filled-bg": "--a-surface-alt-2",
|
||||
"--ac-tag-alt-2-filled-text": "--a-text-on-alt-2",
|
||||
"--ac-tag-alt-2-moderate-bg": "--a-surface-alt-2-moderate",
|
||||
"--ac-tag-alt-2-moderate-text": "--a-text-default",
|
||||
"--ac-tag-alt-3-border": "--a-border-alt-3",
|
||||
"--ac-tag-alt-3-bg": "--a-surface-alt-3-subtle",
|
||||
"--ac-tag-alt-3-text": "--a-text-default",
|
||||
"--ac-tag-alt-3-filled-bg": "--a-surface-alt-3",
|
||||
"--ac-tag-alt-3-filled-text": "--a-text-on-alt-3"
|
||||
"--ac-tag-alt-3-filled-text": "--a-text-on-alt-3",
|
||||
"--ac-tag-alt-3-moderate-bg": "--a-surface-alt-3-moderate",
|
||||
"--ac-tag-alt-3-moderate-text": "--a-text-default"
|
||||
},
|
||||
"togglegroup": {
|
||||
"--ac-toggle-group-bg": "--a-surface-transparent",
|
||||
|
||||
@@ -1,5 +1,30 @@
|
||||
# @navikt/ds-react
|
||||
|
||||
## 3.4.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/aksel-icons@3.4.2
|
||||
|
||||
## 3.4.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/aksel-icons@3.4.1
|
||||
|
||||
## 3.4.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#2010](https://github.com/navikt/aksel/pull/2010) [`b958d41a2`](https://github.com/navikt/aksel/commit/b958d41a20c66327658514fcf24ae20893c9531a) Thanks [@HalvorHaugan](https://github.com/HalvorHaugan)! - Ny variant "moderate" i Tag
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/aksel-icons@3.4.0
|
||||
|
||||
## 3.3.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-react",
|
||||
"version": "3.3.1",
|
||||
"version": "3.4.2",
|
||||
"description": "Aksel react-components for NAV designsystem",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"license": "MIT",
|
||||
@@ -38,7 +38,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@floating-ui/react": "0.24.1",
|
||||
"@navikt/aksel-icons": "^3.3.1",
|
||||
"@navikt/aksel-icons": "^3.4.2",
|
||||
"@radix-ui/react-tabs": "1.0.0",
|
||||
"@radix-ui/react-toggle-group": "1.0.0",
|
||||
"clsx": "^1.2.1",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { forwardRef, HTMLAttributes } from "react";
|
||||
import cl from "clsx";
|
||||
import { BodyShort, Detail } from "..";
|
||||
import { BodyShort } from "..";
|
||||
|
||||
export interface TagProps extends HTMLAttributes<HTMLSpanElement> {
|
||||
children: React.ReactNode;
|
||||
@@ -10,20 +10,28 @@ export interface TagProps extends HTMLAttributes<HTMLSpanElement> {
|
||||
variant:
|
||||
| "warning"
|
||||
| "warning-filled"
|
||||
| "warning-moderate"
|
||||
| "error"
|
||||
| "error-filled"
|
||||
| "error-moderate"
|
||||
| "info"
|
||||
| "info-filled"
|
||||
| "info-moderate"
|
||||
| "success"
|
||||
| "success-filled"
|
||||
| "success-moderate"
|
||||
| "neutral"
|
||||
| "neutral-filled"
|
||||
| "neutral-moderate"
|
||||
| "alt1"
|
||||
| "alt1-filled"
|
||||
| "alt1-moderate"
|
||||
| "alt2"
|
||||
| "alt2-filled"
|
||||
| "alt2-moderate"
|
||||
| "alt3"
|
||||
| "alt3-filled";
|
||||
| "alt3-filled"
|
||||
| "alt3-moderate";
|
||||
/**
|
||||
* @default "medium"
|
||||
*/
|
||||
@@ -31,24 +39,20 @@ export interface TagProps extends HTMLAttributes<HTMLSpanElement> {
|
||||
}
|
||||
|
||||
export const Tag = forwardRef<HTMLSpanElement, TagProps>(
|
||||
({ className, variant, size = "medium", ...rest }, ref) => {
|
||||
const Component = size === "medium" ? BodyShort : Detail;
|
||||
|
||||
return (
|
||||
<Component
|
||||
{...rest}
|
||||
ref={ref}
|
||||
as="span"
|
||||
size={size === "medium" ? "medium" : "small"}
|
||||
className={cl(
|
||||
"navds-tag",
|
||||
className,
|
||||
`navds-tag--${variant}`,
|
||||
`navds-tag--${size}`
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
({ className, variant, size = "medium", ...rest }, ref) => (
|
||||
<BodyShort
|
||||
{...rest}
|
||||
ref={ref}
|
||||
as="span"
|
||||
size={size === "medium" ? "medium" : "small"}
|
||||
className={cl(
|
||||
"navds-tag",
|
||||
className,
|
||||
`navds-tag--${variant}`,
|
||||
`navds-tag--${size}`
|
||||
)}
|
||||
/>
|
||||
)
|
||||
);
|
||||
|
||||
export default Tag;
|
||||
@@ -1,62 +1,8 @@
|
||||
import React from "react";
|
||||
import { Tag } from ".";
|
||||
import type { Meta } from "@storybook/react";
|
||||
import { Tag, TagProps } from ".";
|
||||
|
||||
export default {
|
||||
title: "ds-react/Tag",
|
||||
component: Tag,
|
||||
argTypes: {
|
||||
variant: {
|
||||
defaultValue: "info",
|
||||
control: {
|
||||
type: "radio",
|
||||
options: [
|
||||
"warning",
|
||||
"error",
|
||||
"info",
|
||||
"success",
|
||||
"neutral",
|
||||
"alt1",
|
||||
"alt2",
|
||||
"alt3",
|
||||
"warning-filled",
|
||||
"error-filled",
|
||||
"info-filled",
|
||||
"success-filled",
|
||||
"neutral-filled",
|
||||
"alt1-filled",
|
||||
"alt2-filled",
|
||||
"alt3-filled",
|
||||
],
|
||||
},
|
||||
},
|
||||
size: {
|
||||
defaultValue: "medium",
|
||||
control: {
|
||||
type: "radio",
|
||||
options: ["xsmall", "small", "medium"],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const variants: Array<
|
||||
| "warning"
|
||||
| "warning-filled"
|
||||
| "error"
|
||||
| "error-filled"
|
||||
| "info"
|
||||
| "info-filled"
|
||||
| "success"
|
||||
| "success-filled"
|
||||
| "neutral"
|
||||
| "neutral-filled"
|
||||
| "alt1"
|
||||
| "alt1-filled"
|
||||
| "alt2"
|
||||
| "alt2-filled"
|
||||
| "alt3"
|
||||
| "alt3-filled"
|
||||
> = [
|
||||
const variants: TagProps["variant"][] = [
|
||||
"warning",
|
||||
"error",
|
||||
"info",
|
||||
@@ -73,8 +19,37 @@ const variants: Array<
|
||||
"alt1-filled",
|
||||
"alt2-filled",
|
||||
"alt3-filled",
|
||||
"warning-moderate",
|
||||
"error-moderate",
|
||||
"info-moderate",
|
||||
"success-moderate",
|
||||
"neutral-moderate",
|
||||
"alt1-moderate",
|
||||
"alt2-moderate",
|
||||
"alt3-moderate",
|
||||
];
|
||||
|
||||
export default {
|
||||
title: "ds-react/Tag",
|
||||
component: Tag,
|
||||
argTypes: {
|
||||
variant: {
|
||||
defaultValue: "info",
|
||||
control: {
|
||||
type: "radio",
|
||||
},
|
||||
options: variants,
|
||||
},
|
||||
size: {
|
||||
defaultValue: "medium",
|
||||
control: {
|
||||
type: "radio",
|
||||
},
|
||||
options: ["xsmall", "small", "medium"],
|
||||
},
|
||||
},
|
||||
} satisfies Meta<typeof Tag>;
|
||||
|
||||
export const Default = {
|
||||
render: (props) => (
|
||||
<Tag variant={props.variant} size={props.size}>
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @navikt/ds-tailwind
|
||||
|
||||
## 3.4.2
|
||||
|
||||
## 3.4.1
|
||||
|
||||
## 3.4.0
|
||||
|
||||
## 3.3.1
|
||||
|
||||
## 3.3.0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-tailwind",
|
||||
"version": "3.3.1",
|
||||
"version": "3.4.2",
|
||||
"description": "Tailwind config based on @navikt/ds-tokens",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"keywords": [
|
||||
@@ -22,7 +22,7 @@
|
||||
"directory": "@navikt/core/tailwind"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@navikt/ds-tokens": "^3.3.1",
|
||||
"@navikt/ds-tokens": "^3.4.2",
|
||||
"@types/jest": "^29.0.0",
|
||||
"color": "4.2.3",
|
||||
"jest": "^29.0.0",
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
# @navikt/ds-tokens
|
||||
|
||||
## 3.4.2
|
||||
|
||||
## 3.4.1
|
||||
|
||||
## 3.4.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#2010](https://github.com/navikt/aksel/pull/2010) [`b958d41a2`](https://github.com/navikt/aksel/commit/b958d41a20c66327658514fcf24ae20893c9531a) Thanks [@HalvorHaugan](https://github.com/HalvorHaugan)! - Ny variant "moderate" i Tag
|
||||
|
||||
## 3.3.1
|
||||
|
||||
## 3.3.0
|
||||
|
||||
@@ -270,6 +270,7 @@
|
||||
"name": "--a-surface-neutral-subtle-hover",
|
||||
"value": "rgba(0, 0, 0, 0.1)"
|
||||
},
|
||||
{ "name": "--a-surface-neutral-moderate", "value": "rgba(0, 0, 0, 0.1)" },
|
||||
{ "name": "--a-surface-neutral", "value": "rgba(89, 89, 89, 1)" },
|
||||
{ "name": "--a-surface-neutral-hover", "value": "rgba(64, 64, 64, 1)" },
|
||||
{ "name": "--a-surface-neutral-selected", "value": "rgba(38, 38, 38, 1)" },
|
||||
@@ -279,6 +280,10 @@
|
||||
"name": "--a-surface-success-subtle-hover",
|
||||
"value": "rgba(153, 222, 173, 1)"
|
||||
},
|
||||
{
|
||||
"name": "--a-surface-success-moderate",
|
||||
"value": "rgba(153, 222, 173, 1)"
|
||||
},
|
||||
{ "name": "--a-surface-success", "value": "rgba(6, 137, 58, 1)" },
|
||||
{ "name": "--a-surface-success-hover", "value": "rgba(0, 124, 46, 1)" },
|
||||
{ "name": "--a-surface-danger-subtle", "value": "rgba(255, 194, 194, 1)" },
|
||||
@@ -286,10 +291,18 @@
|
||||
"name": "--a-surface-danger-subtle-hover",
|
||||
"value": "rgba(246, 130, 130, 1)"
|
||||
},
|
||||
{
|
||||
"name": "--a-surface-danger-moderate",
|
||||
"value": "rgba(246, 130, 130, 1)"
|
||||
},
|
||||
{ "name": "--a-surface-danger", "value": "rgba(195, 0, 0, 1)" },
|
||||
{ "name": "--a-surface-danger-hover", "value": "rgba(173, 0, 0, 1)" },
|
||||
{ "name": "--a-surface-danger-active", "value": "rgba(140, 0, 0, 1)" },
|
||||
{ "name": "--a-surface-warning-subtle", "value": "rgba(255, 236, 204, 1)" },
|
||||
{
|
||||
"name": "--a-surface-warning-moderate",
|
||||
"value": "rgba(255, 215, 153, 1)"
|
||||
},
|
||||
{ "name": "--a-surface-warning", "value": "rgba(255, 145, 0, 1)" },
|
||||
{
|
||||
"name": "--a-surface-warning-subtle-hover",
|
||||
@@ -300,13 +313,17 @@
|
||||
"name": "--a-surface-info-subtle-hover",
|
||||
"value": "rgba(181, 241, 255, 1)"
|
||||
},
|
||||
{ "name": "--a-surface-info-moderate", "value": "rgba(181, 241, 255, 1)" },
|
||||
{ "name": "--a-surface-info", "value": "rgba(102, 203, 236, 1)" },
|
||||
{ "name": "--a-surface-alt-1", "value": "rgba(130, 105, 162, 1)" },
|
||||
{ "name": "--a-surface-alt-1-subtle", "value": "rgba(224, 216, 233, 1)" },
|
||||
{ "name": "--a-surface-alt-1-moderate", "value": "rgba(192, 178, 210, 1)" },
|
||||
{ "name": "--a-surface-alt-2", "value": "rgba(193, 203, 51, 1)" },
|
||||
{ "name": "--a-surface-alt-2-subtle", "value": "rgba(249, 252, 204, 1)" },
|
||||
{ "name": "--a-surface-alt-2-moderate", "value": "rgba(236, 243, 153, 1)" },
|
||||
{ "name": "--a-surface-alt-3", "value": "rgba(0, 91, 130, 1)" },
|
||||
{ "name": "--a-surface-alt-3-subtle", "value": "rgba(204, 226, 240, 1)" },
|
||||
{ "name": "--a-surface-alt-3-moderate", "value": "rgba(153, 196, 221, 1)" },
|
||||
{ "name": "--a-surface-alt-3-strong", "value": "rgba(0, 52, 83, 1)" }
|
||||
],
|
||||
"semantic-bg": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-tokens",
|
||||
"version": "3.3.1",
|
||||
"version": "3.4.2",
|
||||
"description": "Design-tokens for NAV designsystem",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"keywords": [
|
||||
|
||||
@@ -137,6 +137,9 @@
|
||||
"value": "{a.grayalpha.100.value}"
|
||||
}
|
||||
},
|
||||
"moderate": {
|
||||
"value": "{a.grayalpha.200.value}"
|
||||
},
|
||||
"hover": {
|
||||
"value": "{a.gray.800.value}"
|
||||
},
|
||||
@@ -156,6 +159,9 @@
|
||||
"hover": { "value": "{a.green.200.value}" },
|
||||
"@": { "value": "{a.green.100.value}" }
|
||||
},
|
||||
"moderate": {
|
||||
"value": "{a.green.200.value}"
|
||||
},
|
||||
"@": { "value": "{a.green.500.value}" },
|
||||
"hover": { "value": "{a.green.600.value}" }
|
||||
},
|
||||
@@ -165,6 +171,9 @@
|
||||
"hover": { "value": "{a.red.200.value}" },
|
||||
"@": { "value": "{a.red.100.value}" }
|
||||
},
|
||||
"moderate": {
|
||||
"value": "{a.red.200.value}"
|
||||
},
|
||||
"hover": {
|
||||
"value": "{a.red.600.value}"
|
||||
},
|
||||
@@ -179,6 +188,9 @@
|
||||
"hover": { "value": "{a.orange.200.value}" },
|
||||
"@": { "value": "{a.orange.100.value}" }
|
||||
},
|
||||
"moderate": {
|
||||
"value": "{a.orange.200.value}"
|
||||
},
|
||||
"@": { "value": "{a.orange.500.value}" }
|
||||
},
|
||||
|
||||
@@ -187,19 +199,25 @@
|
||||
"hover": { "value": "{a.lightblue.200.value}" },
|
||||
"@": { "value": "{a.lightblue.100.value}" }
|
||||
},
|
||||
"moderate": {
|
||||
"value": "{a.lightblue.200.value}"
|
||||
},
|
||||
"@": { "value": "{a.lightblue.500.value}" }
|
||||
},
|
||||
|
||||
"alt1": {
|
||||
"subtle": { "value": "{a.purple.100.value}" },
|
||||
"moderate": { "value": "{a.purple.200.value}" },
|
||||
"@": { "value": "{a.purple.400.value}" }
|
||||
},
|
||||
"alt2": {
|
||||
"subtle": { "value": "{a.limegreen.100.value}" },
|
||||
"moderate": { "value": "{a.limegreen.200.value}" },
|
||||
"@": { "value": "{a.limegreen.400.value}" }
|
||||
},
|
||||
"alt3": {
|
||||
"subtle": { "value": "{a.deepblue.100.value}" },
|
||||
"moderate": { "value": "{a.deepblue.200.value}" },
|
||||
"strong": { "value": "{a.deepblue.800.value}" },
|
||||
"@": { "value": "{a.deepblue.500.value}" }
|
||||
}
|
||||
|
||||
@@ -1,194 +1,52 @@
|
||||
import React from "react";
|
||||
import { Meta } from "@storybook/react";
|
||||
import * as tokens from "../dist/tokens.js";
|
||||
import tokens from "../docs.json";
|
||||
|
||||
export default {
|
||||
title: "ds-tokens/Colors",
|
||||
} as Meta;
|
||||
|
||||
const globalColor = (
|
||||
color:
|
||||
| "gray"
|
||||
| "grayalpha"
|
||||
| "blue"
|
||||
| "red"
|
||||
| "orange"
|
||||
| "limegreen"
|
||||
| "deepblue"
|
||||
| "green"
|
||||
| "lightblue"
|
||||
| "purple"
|
||||
): { [key: string]: string } => {
|
||||
return Object.entries(tokens).reduce((old, [key, val]) => {
|
||||
if (color === "gray" && key.toLowerCase().includes("alpha")) {
|
||||
return { ...old };
|
||||
}
|
||||
return key.toLowerCase().startsWith(`a${color}`)
|
||||
? { ...old, [key]: val }
|
||||
: { ...old };
|
||||
}, {});
|
||||
};
|
||||
|
||||
const RenderGlobal = ({ color }) => (
|
||||
const ColorGroups = ({ prefix }: { prefix: string }) => (
|
||||
<div>
|
||||
{Object.entries(globalColor(color))
|
||||
.sort((a, b) => (a[0].endsWith("50") ? -1 : 1))
|
||||
.map(([key, val]) => (
|
||||
<div
|
||||
style={{
|
||||
background: val,
|
||||
width: "50rem",
|
||||
height: "5rem",
|
||||
position: "relative",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
background: "rgba(39,39,39,0.4)",
|
||||
width: "fit-content",
|
||||
color: "white",
|
||||
padding: 2,
|
||||
fontSize: 14,
|
||||
}}
|
||||
>
|
||||
{`${key}: ${val}`}
|
||||
{Object.entries(tokens)
|
||||
.filter(([group]) => group.startsWith(prefix))
|
||||
.map(([group, groupTokens]) => {
|
||||
const groupName = group.replace(prefix, "");
|
||||
return (
|
||||
<div className="colgap">
|
||||
<h2>
|
||||
{groupName.charAt(0).toLocaleUpperCase() + groupName.substring(1)}
|
||||
</h2>
|
||||
{groupTokens.map((color) => (
|
||||
<div
|
||||
style={{
|
||||
background: color.value,
|
||||
width: "50rem",
|
||||
height: "5rem",
|
||||
position: "relative",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
background: "rgba(39,39,39,0.4)",
|
||||
width: "fit-content",
|
||||
color: "white",
|
||||
padding: 2,
|
||||
fontSize: 14,
|
||||
}}
|
||||
>
|
||||
{color.name}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
export const GlobalGray = () => <RenderGlobal color="gray" />;
|
||||
export const GlobalGrayAlpha = () => <RenderGlobal color="grayalpha" />;
|
||||
export const GlobalBlue = () => <RenderGlobal color="blue" />;
|
||||
export const GlobalDeepBlue = () => <RenderGlobal color="deepblue" />;
|
||||
export const GlobalLightBlue = () => <RenderGlobal color="lightblue" />;
|
||||
export const GlobalRed = () => <RenderGlobal color="red" />;
|
||||
export const GlobalOrange = () => <RenderGlobal color="orange" />;
|
||||
export const GlobalGreen = () => <RenderGlobal color="green" />;
|
||||
export const GlobalLimeGreen = () => <RenderGlobal color="limegreen" />;
|
||||
export const GlobalPurple = () => <RenderGlobal color="purple" />;
|
||||
|
||||
const semanticTokens = [
|
||||
"--a-icon-on-warning",
|
||||
"--a-icon-on-info",
|
||||
"--a-icon-on-danger",
|
||||
"--a-icon-on-success",
|
||||
"--a-icon-on-action",
|
||||
"--a-icon-on-inverted",
|
||||
"--a-icon-on-neutral",
|
||||
"--a-icon-alt-1",
|
||||
"--a-icon-info",
|
||||
"--a-icon-warning",
|
||||
"--a-icon-danger",
|
||||
"--a-icon-success",
|
||||
"--a-icon-action-selected",
|
||||
"--a-icon-subtle",
|
||||
"--a-icon-default",
|
||||
"--a-surface-alt-3",
|
||||
"--a-surface-alt-3-strong",
|
||||
"--a-surface-alt-3-subtle",
|
||||
"--a-surface-alt-2",
|
||||
"--a-surface-alt-2-subtle",
|
||||
"--a-surface-alt-1",
|
||||
"--a-surface-alt-1-subtle",
|
||||
"--a-surface-info",
|
||||
"--a-surface-info-subtle",
|
||||
"--a-surface-info-subtle-hover",
|
||||
"--a-surface-warning",
|
||||
"--a-surface-warning-subtle",
|
||||
"--a-surface-warning-subtle-hover",
|
||||
"--a-surface-danger",
|
||||
"--a-surface-danger-active",
|
||||
"--a-surface-danger-hover",
|
||||
"--a-surface-danger-subtle",
|
||||
"--a-surface-danger-subtle-hover",
|
||||
"--a-surface-success",
|
||||
"--a-surface-success-subtle",
|
||||
"--a-surface-success-subtle-hover",
|
||||
"--a-surface-neutral",
|
||||
"--a-surface-neutral-selected",
|
||||
"--a-surface-neutral-selected-hover",
|
||||
"--a-surface-neutral-active",
|
||||
"--a-surface-neutral-hover",
|
||||
"--a-surface-neutral-subtle",
|
||||
"--a-surface-neutral-subtle-hover",
|
||||
"--a-surface-action",
|
||||
"--a-surface-action-selected",
|
||||
"--a-surface-action-selected-hover",
|
||||
"--a-surface-action-active",
|
||||
"--a-surface-action-hover",
|
||||
"--a-surface-action-subtle",
|
||||
"--a-surface-action-subtle-hover",
|
||||
"--a-surface-inverted",
|
||||
"--a-surface-inverted-active",
|
||||
"--a-surface-inverted-hover",
|
||||
"--a-surface-transparent",
|
||||
"--a-surface-subtle",
|
||||
"--a-surface-selected",
|
||||
"--a-surface-active",
|
||||
"--a-surface-hover",
|
||||
"--a-surface-default",
|
||||
"--a-bg-subtle",
|
||||
"--a-bg-default",
|
||||
"--a-text-on-info",
|
||||
"--a-text-on-warning",
|
||||
"--a-text-on-danger",
|
||||
"--a-text-on-success",
|
||||
"--a-text-on-action",
|
||||
"--a-text-on-neutral",
|
||||
"--a-text-on-inverted",
|
||||
"--a-text-action",
|
||||
"--a-text-action-selected",
|
||||
"--a-text-danger",
|
||||
"--a-text-visited",
|
||||
"--a-text-subtle",
|
||||
"--a-text-default",
|
||||
"--a-border-on-inverted",
|
||||
"--a-border-focus",
|
||||
"--a-border-focus-on-inverted",
|
||||
"--a-border-info",
|
||||
"--a-border-warning",
|
||||
"--a-border-danger",
|
||||
"--a-border-success",
|
||||
"--a-border-selected-selected",
|
||||
"--a-border-action",
|
||||
"--a-border-subtle",
|
||||
"--a-border-divider",
|
||||
"--a-border-strong",
|
||||
"--a-border-default",
|
||||
];
|
||||
|
||||
export const Semantic = () => {
|
||||
return (
|
||||
<div className="colgap">
|
||||
{semanticTokens.map((key) => (
|
||||
<div
|
||||
style={{
|
||||
background: `var(${key})`,
|
||||
width: "50rem",
|
||||
height: "5rem",
|
||||
position: "relative",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
background: "rgba(39,39,39,0.4)",
|
||||
width: "fit-content",
|
||||
color: "white",
|
||||
padding: 2,
|
||||
fontSize: 14,
|
||||
}}
|
||||
>
|
||||
{key}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
export const Global = () => <ColorGroups prefix="global-" />;
|
||||
export const Semantic = () => <ColorGroups prefix="semantic-" />;
|
||||
@@ -1,5 +1,11 @@
|
||||
# @navikt/ds-icons
|
||||
|
||||
## 3.4.2
|
||||
|
||||
## 3.4.1
|
||||
|
||||
## 3.4.0
|
||||
|
||||
## 3.3.1
|
||||
|
||||
## 3.3.0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-icons",
|
||||
"version": "3.3.1",
|
||||
"version": "3.4.2",
|
||||
"description": "Aksel icons for NAV",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"repository": {
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @navikt/ds-css-internal
|
||||
|
||||
## 3.4.2
|
||||
|
||||
## 3.4.1
|
||||
|
||||
## 3.4.0
|
||||
|
||||
## 3.3.1
|
||||
|
||||
## 3.3.0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-css-internal",
|
||||
"version": "3.3.1",
|
||||
"version": "3.4.2",
|
||||
"description": "CSS for NAV internal Designsystem-components",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"keywords": [
|
||||
|
||||
@@ -1,5 +1,29 @@
|
||||
# @navikt/ds-react-internal
|
||||
|
||||
## 3.4.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-react@3.4.2
|
||||
- @navikt/aksel-icons@3.4.2
|
||||
|
||||
## 3.4.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-react@3.4.1
|
||||
- @navikt/aksel-icons@3.4.1
|
||||
|
||||
## 3.4.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b958d41a2`](https://github.com/navikt/aksel/commit/b958d41a20c66327658514fcf24ae20893c9531a)]:
|
||||
- @navikt/ds-react@3.4.0
|
||||
- @navikt/aksel-icons@3.4.0
|
||||
|
||||
## 3.3.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-react-internal",
|
||||
"version": "3.3.1",
|
||||
"version": "3.4.2",
|
||||
"description": "Aksel react components for internal UIs in NAV",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"license": "MIT",
|
||||
@@ -37,8 +37,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@floating-ui/react": "0.24.1",
|
||||
"@navikt/aksel-icons": "^3.3.1",
|
||||
"@navikt/ds-react": "^3.3.1",
|
||||
"@navikt/aksel-icons": "^3.4.2",
|
||||
"@navikt/ds-react": "^3.4.2",
|
||||
"clsx": "^1.1.1",
|
||||
"copy-to-clipboard": "^3.3.1"
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<h1 align="center">
|
||||
<img src="https://user-images.githubusercontent.com/26967723/164701858-e8237611-1285-4c68-b9e3-e047499b94cf.svg" />
|
||||
<br/>Aksel
|
||||
<img src="/aksel.nav.no/website/public/favicon.svg" style="width:13rem"/>
|
||||
<br/><br/>Aksel
|
||||
</h1>
|
||||
|
||||
<div align="center">
|
||||
@@ -14,8 +14,8 @@
|
||||
<a href="https://github.com/navikt/aksel/pulls">
|
||||
<img src="https://img.shields.io/badge/PRs-welcome-green.svg?color=%23262626"" />
|
||||
</a>
|
||||
<a href="https://www.npmjs.com/package/@navikt/ds-css"><img alt="npm" src="https://img.shields.io/npm/v/@navikt/ds-css?label=version"></a>
|
||||
</div>
|
||||
<div><a href="https://www.npmjs.com/package/@navikt/ds-css"><img alt="npm" src="https://img.shields.io/npm/v/@navikt/ds-css?label=version"></a></div>
|
||||
<br/>
|
||||
<a href="https://aksel.nav.no">Nettside</a> | <a href="https://github.com/navikt/aksel/issues">Issues</a>
|
||||
<br/>
|
||||
|
||||
@@ -15,15 +15,15 @@
|
||||
"website"
|
||||
],
|
||||
"dependencies": {
|
||||
"@navikt/aksel-icons": "^3.3.1",
|
||||
"@navikt/ds-codemod": "^3.3.1",
|
||||
"@navikt/ds-css": "^3.3.1",
|
||||
"@navikt/ds-css-internal": "^3.3.1",
|
||||
"@navikt/ds-icons": "^3.3.1",
|
||||
"@navikt/ds-react": "^3.3.1",
|
||||
"@navikt/ds-react-internal": "^3.3.1",
|
||||
"@navikt/ds-tailwind": "^3.3.1",
|
||||
"@navikt/ds-tokens": "^3.3.1"
|
||||
"@navikt/aksel-icons": "^3.4.2",
|
||||
"@navikt/ds-codemod": "^3.4.2",
|
||||
"@navikt/ds-css": "^3.4.2",
|
||||
"@navikt/ds-css-internal": "^3.4.2",
|
||||
"@navikt/ds-icons": "^3.4.2",
|
||||
"@navikt/ds-react": "^3.4.2",
|
||||
"@navikt/ds-react-internal": "^3.4.2",
|
||||
"@navikt/ds-tailwind": "^3.4.2",
|
||||
"@navikt/ds-tokens": "^3.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier-plugin-tailwindcss": "^0.2.3"
|
||||
|
||||
@@ -120,17 +120,18 @@ export const IconPage = ({ name }: { name: string }) => {
|
||||
<TitleLinks />
|
||||
</div>
|
||||
|
||||
<div className="bg-surface-default shadow-small ring-border-subtle z-10 mt-16 mb-8 h-full w-full rounded-2xl ring-1">
|
||||
<div className="bg-surface-default shadow-small ring-border-subtle z-10 mb-8 mt-16 h-full w-full rounded-2xl ring-1">
|
||||
<div className="border-b-border-subtle bg-surface-default sticky top-0 z-20 grid items-center rounded-t-2xl border-b p-1">
|
||||
<form
|
||||
onSubmit={(e) => e.preventDefault()}
|
||||
className="flex h-fit w-full items-center gap-4 py-2 px-4"
|
||||
className="flex h-fit w-full items-center gap-4 px-4 py-2"
|
||||
>
|
||||
<div className="min-w-40">
|
||||
<ToggleGroup
|
||||
value={toggle}
|
||||
onChange={(v) => setToggle(v as any)}
|
||||
variant="neutral"
|
||||
aria-label="Velg ikonvariant"
|
||||
>
|
||||
<ToggleGroup.Item value="stroke">Stroke</ToggleGroup.Item>
|
||||
<ToggleGroup.Item value="fill">Fill</ToggleGroup.Item>
|
||||
@@ -250,7 +251,7 @@ export const IconPage = ({ name }: { name: string }) => {
|
||||
closeButton={false}
|
||||
aria-modal
|
||||
aria-label={`${name} ikon`}
|
||||
className="bg-surface-default focus-visible:shadow-focus z-modal absolute block h-full overflow-y-auto rounded py-6 px-2 focus:outline-none sm:px-6"
|
||||
className="bg-surface-default focus-visible:shadow-focus z-modal absolute block h-full overflow-y-auto rounded px-2 py-6 focus:outline-none sm:px-6"
|
||||
>
|
||||
{name && <IconSidebar name={name} focusRef={focusRef} />}
|
||||
</Modal>
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import * as Icons from "@navikt/aksel-icons";
|
||||
import meta from "@navikt/aksel-icons/metadata";
|
||||
import { Button, Heading, Tooltip } from "@navikt/ds-react";
|
||||
import { Button, CopyButton, Heading, Tooltip } from "@navikt/ds-react";
|
||||
import { SuggestionBlock } from "components/website-modules/suggestionblock";
|
||||
import {
|
||||
AmplitudeEvents,
|
||||
logAmplitudeEvent,
|
||||
} from "components/website-modules/utils/amplitude";
|
||||
import copy from "copy-to-clipboard";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/router";
|
||||
import Highlight, { defaultProps } from "prism-react-renderer";
|
||||
@@ -21,8 +20,6 @@ export const IconSidebar = ({
|
||||
focusRef: any;
|
||||
}) => {
|
||||
const SelectedIcon = Icons[`${name}Icon`];
|
||||
const [resentCopy, setResentCopy] = useState<"svg" | "react" | "import">();
|
||||
const timeoutRef = useRef<NodeJS.Timeout>();
|
||||
const wrapperRef = useRef<HTMLDivElement>(null);
|
||||
const [blob, setBlob]: any = useState();
|
||||
const router = useRouter();
|
||||
@@ -48,19 +45,6 @@ export const IconSidebar = ({
|
||||
});
|
||||
}
|
||||
|
||||
const handleCopy = (copyStr: string, src: "svg" | "react" | "import") => {
|
||||
copy(copyStr);
|
||||
timeoutRef.current && clearTimeout(timeoutRef.current);
|
||||
setResentCopy(src);
|
||||
timeoutRef.current = setTimeout(() => {
|
||||
setResentCopy(undefined);
|
||||
}, 2000);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
return () => timeoutRef.current && clearTimeout(timeoutRef.current);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (wrapperRef.current) {
|
||||
wrapperRef.current.focus({ preventScroll: true });
|
||||
@@ -149,25 +133,13 @@ export const IconSidebar = ({
|
||||
<div className="ring-border-subtle rounded-lg ring-1">
|
||||
<div className="border-b-border-subtle text-medium flex items-center justify-between border-b px-3 py-1">
|
||||
<span>Import</span>
|
||||
<Tooltip
|
||||
open={resentCopy === "import" || undefined}
|
||||
content={resentCopy === "import" ? "Kopiert!" : "Kopier"}
|
||||
>
|
||||
<button
|
||||
onClick={() =>
|
||||
handleCopy(
|
||||
`import {
|
||||
<Tooltip content="Kopier React-import">
|
||||
<CopyButton
|
||||
size="small"
|
||||
copyText={`import {
|
||||
${name}Icon
|
||||
} from '@navikt/aksel-icons';`,
|
||||
"import"
|
||||
)
|
||||
}
|
||||
className="hover:bg-surface-hover grid aspect-square w-8 place-content-center rounded text-xl"
|
||||
>
|
||||
<Icons.ClipboardIcon
|
||||
title={resentCopy === "import" ? "Kopiert!" : "Kopier"}
|
||||
/>
|
||||
</button>
|
||||
} from '@navikt/aksel-icons';`}
|
||||
/>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<Highlight
|
||||
@@ -198,20 +170,11 @@ export const IconSidebar = ({
|
||||
<div className="ring-border-subtle mt-3 rounded-lg ring-1">
|
||||
<div className="border-b-border-subtle text-medium flex items-center justify-between border-b px-3 py-1">
|
||||
<span>React</span>
|
||||
<Tooltip
|
||||
content={resentCopy === "react" ? "Kopiert!" : "Kopier"}
|
||||
open={resentCopy === "react" || undefined}
|
||||
>
|
||||
<button
|
||||
onClick={() =>
|
||||
handleCopy(`<${name}Icon title="a11y-title" />`, "react")
|
||||
}
|
||||
className="hover:bg-surface-hover grid aspect-square w-8 place-content-center rounded text-xl"
|
||||
>
|
||||
<Icons.ClipboardIcon
|
||||
title={resentCopy === "import" ? "Kopiert!" : "Kopier"}
|
||||
/>
|
||||
</button>
|
||||
<Tooltip content="Kopier React-snippet">
|
||||
<CopyButton
|
||||
size="small"
|
||||
copyText={`<${name}Icon title="a11y-title" />`}
|
||||
/>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<Highlight
|
||||
@@ -240,23 +203,11 @@ export const IconSidebar = ({
|
||||
<div className="ring-border-subtle mt-3 rounded-lg ring-1">
|
||||
<div className="border-b-border-subtle text-medium flex items-center justify-between border-b px-3 py-1">
|
||||
<span>SVG</span>
|
||||
<Tooltip
|
||||
content={resentCopy === "svg" ? "Kopiert!" : "Kopier"}
|
||||
open={resentCopy === "svg" || undefined}
|
||||
>
|
||||
<button
|
||||
onClick={() =>
|
||||
handleCopy(
|
||||
ReactDOMServer.renderToString(<SelectedIcon />),
|
||||
"svg"
|
||||
)
|
||||
}
|
||||
className="hover:bg-surface-hover grid aspect-square w-8 place-content-center rounded text-xl"
|
||||
>
|
||||
<Icons.ClipboardIcon
|
||||
title={resentCopy === "import" ? "Kopiert!" : "Kopier"}
|
||||
/>
|
||||
</button>
|
||||
<Tooltip content="Kopier SVG-kode">
|
||||
<CopyButton
|
||||
size="small"
|
||||
copyText={ReactDOMServer.renderToString(<SelectedIcon />)}
|
||||
/>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<Highlight
|
||||
|
||||
@@ -55,9 +55,11 @@ const SuggestionBlockIcon = ({
|
||||
<div className={cl("mb-12 mt-6 flex gap-3 rounded-lg py-4 ")}>
|
||||
<span className="shrink-0 text-2xl">{options[variant]?.icon}</span>
|
||||
<div className="grid">
|
||||
<Heading size="small" level="2">
|
||||
{options[variant]?.heading}
|
||||
</Heading>
|
||||
{options[variant]?.heading && (
|
||||
<Heading size="small" level="2">
|
||||
{options[variant]?.heading}
|
||||
</Heading>
|
||||
)}
|
||||
<BodyLong className="mt-2">{options[variant]?.text}</BodyLong>
|
||||
<Button
|
||||
variant="secondary"
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import { Search } from "@navikt/ds-react";
|
||||
import { withDsExample } from "components/website-modules/examples/withDsExample";
|
||||
|
||||
const Example = () => {
|
||||
return (
|
||||
<form>
|
||||
<Search label="Søk alle NAV sine sider" variant="secondary">
|
||||
<Search.Button type="button" />
|
||||
</Search>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
export default withDsExample(Example);
|
||||
|
||||
/* Storybook story */
|
||||
export const Demo = {
|
||||
render: Example,
|
||||
desc: "Children kan erstatte knapp hvis man trenger eget ikon eller 'type'-prop",
|
||||
};
|
||||
|
||||
export const args = {
|
||||
index: 8,
|
||||
};
|
||||
@@ -6,6 +6,7 @@ const Example = () => {
|
||||
<div className="flex gap-2">
|
||||
<Tag variant="alt1">Alt1</Tag>
|
||||
<Tag variant="alt1-filled">Alt1</Tag>
|
||||
<Tag variant="alt1-moderate">Alt1</Tag>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -6,6 +6,7 @@ const Example = () => {
|
||||
<div className="flex gap-2">
|
||||
<Tag variant="alt2">Alt2</Tag>
|
||||
<Tag variant="alt2-filled">Alt2</Tag>
|
||||
<Tag variant="alt2-moderate">Alt2</Tag>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -6,6 +6,7 @@ const Example = () => {
|
||||
<div className="flex gap-2">
|
||||
<Tag variant="alt3">Alt3</Tag>
|
||||
<Tag variant="alt3-filled">Alt3</Tag>
|
||||
<Tag variant="alt3-moderate">Alt3</Tag>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -6,6 +6,7 @@ const Example = () => {
|
||||
<div className="flex gap-2">
|
||||
<Tag variant="error">Error</Tag>
|
||||
<Tag variant="error-filled">Error</Tag>
|
||||
<Tag variant="error-moderate">Error</Tag>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -6,6 +6,7 @@ const Example = () => {
|
||||
<div className="flex gap-2">
|
||||
<Tag variant="info">Info</Tag>
|
||||
<Tag variant="info-filled">Info</Tag>
|
||||
<Tag variant="info-moderate">Info</Tag>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -6,6 +6,7 @@ const Example = () => {
|
||||
<div className="flex gap-2">
|
||||
<Tag variant="neutral">Neutral</Tag>
|
||||
<Tag variant="neutral-filled">Neutral</Tag>
|
||||
<Tag variant="neutral-moderate">Neutral</Tag>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -6,6 +6,7 @@ const Example = () => {
|
||||
<div className="flex gap-2">
|
||||
<Tag variant="success">Success</Tag>
|
||||
<Tag variant="success-filled">Success</Tag>
|
||||
<Tag variant="success-moderate">Success</Tag>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -6,6 +6,7 @@ const Example = () => {
|
||||
<div className="flex gap-2">
|
||||
<Tag variant="warning">Warning</Tag>
|
||||
<Tag variant="warning-filled">Warning</Tag>
|
||||
<Tag variant="warning-moderate">Warning</Tag>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@navikt/ds-css": "3.3.1",
|
||||
"@navikt/ds-react": "3.3.1",
|
||||
"@navikt/ds-css": "3.4.2",
|
||||
"@navikt/ds-react": "3.4.2",
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0"
|
||||
},
|
||||
|
||||
+20
-2
@@ -15,6 +15,7 @@
|
||||
"build:storybook": "storybook build",
|
||||
"test": "yarn workspaces foreach -p run test",
|
||||
"lint": "yarn eslint . && yarn stylelint @navikt/**/*.css",
|
||||
"lint:css": "yarn stylelint @navikt/**/*.css",
|
||||
"changeset": "changeset",
|
||||
"version": "changeset version",
|
||||
"release": "yarn boot && yarn docgen && changeset publish"
|
||||
@@ -26,6 +27,7 @@
|
||||
"@navikt/icons",
|
||||
"@navikt/aksel-icons",
|
||||
"@navikt/aksel-icons/figma-plugin",
|
||||
"@navikt/aksel-stylelint",
|
||||
"@navikt/aksel",
|
||||
"@navikt/community/*",
|
||||
"examples/*",
|
||||
@@ -139,9 +141,25 @@
|
||||
]
|
||||
},
|
||||
"stylelint": {
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"@navikt/core/css/**/*",
|
||||
"@navikt/internal/css/**/*"
|
||||
],
|
||||
"rules": {
|
||||
"aksel/design-token-exists": true,
|
||||
"aksel/design-token-no-component-reference": null,
|
||||
"aksel/design-token-no-global-override": null,
|
||||
"aksel/no-internal-tokens": null,
|
||||
"aksel/no-class-override": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"extends": [
|
||||
"stylelint-config-standard",
|
||||
"stylelint-config-prettier"
|
||||
"stylelint-config-prettier",
|
||||
"./@navikt/aksel-stylelint/dist/recommended"
|
||||
],
|
||||
"plugins": [
|
||||
"stylelint-value-no-unknown-custom-properties",
|
||||
@@ -223,7 +241,7 @@
|
||||
"glob": "^7.1.6",
|
||||
"husky": "^8.0.0",
|
||||
"lint-staged": "13.0.3",
|
||||
"prettier": "2.7.1",
|
||||
"prettier": "2.8.8",
|
||||
"pretty-quick": "^3.1.3",
|
||||
"react": "^18.0.0",
|
||||
"react-docgen-typescript": "2.2.2",
|
||||
|
||||
Reference in new issue
Block a user