Compare commits

..
Author SHA1 Message Date
github-actions[bot]andgithub-actions[bot] 68501b4c8a Version Packages (#2015)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-05-31 14:29:19 +02:00
61c4114214 [WIP] aksel stylelint (#1973)
* working stylelint config + test rule

this commit is a good "base" for developing future stylelint rules

* merge ideas (sortof)

* delete test-rule + add URL to readme section

* flatten json object

* bundle token files at build time

* update lock file deps

* package distribution & version in error message

* rule for internal tokens

* rule for class name override

* remove config props

* fix: emit multiple errors for nodes in postcss-value-parser

* adjust error messages

* some tests

* final tests

* refactor

* no more regex

* update README.md

* update README.md (again)

* readme

* readme and usage example for aksel-design-token-exists

* move README of rule into top-level README

* update README

* update README

* move sources into /src, bookkeeping

* add aksel-stylelint to changeset.fixed

* set exports correctly (exposes ./recommended)

* bookkeeping, cleanup, refactor, remove test files

* Update README.md

* changeset

* fix urls

* update test for aksel-design-token-exists to cover all token files

* add more granular error catching

* cleanup, improve error message

* update tests + fix code that broke tests

* add rule: deprecate classes

* adjust aksel-design-token-exists

* adjust test for no-deprecated-classes

* refactor design-token-exists

* update README

* 📝 update README

* update readme

* refactor: split rules into smaller rules

* fix tests (deduplicate from refactor), fix plugin too

* fix meta name / ruleName -> ruleNamePackage refactor

* set internal dependencies (build time)

* set internal dependencies (build time)

* when building stylelint, always pull latest css & token files

* new lock

* test cache-busting

* ignore some lint rules

* deduplicate rulename

* bring back caching in ci.yml

* 📝 Oppdatert Package.json docs

* more helpful error messages

* 📝 Updated readme

* 📝 Updated prefixes for rules in readme

* 📝 Formateringsfeil i readme

* refactor ruleNames (shorter and better!)

* update one more rule name (I forgor)

* refactor names again (must have namespace)

* 🐛 Fikset intern bruk av lint-regler

* ⬆️ yarn lock sync

---------

Co-authored-by: Halvor Haugan <halvor.haugan@nav.no>
Co-authored-by: Ken <26967723+KenAJoh@users.noreply.github.com>
Co-authored-by: Ken <ken.aleksander@gmail.com>
2023-05-31 14:22:41 +02:00
Halvor HauganandKen b958d41a20 ✨ Tag: ny variant "moderate" (#2010)
Co-authored-by: Ken <26967723+KenAJoh@users.noreply.github.com>
2023-05-31 13:53:30 +02:00
Ken c3905aa2f8 🎨 linetermination fix for windows (#2014) 2023-05-31 13:53:00 +02:00
Ken 812a2347a0 ♿ Mindre uu-fiks for ikonside 2023-05-31 10:18:15 +02:00
Ken deb1c151bb Update README.md 2023-05-30 15:18:26 +02:00
Ken 784d17165d ♻️ Ikonside bruker nå CopyButton 2023-05-30 15:07:18 +02:00
Ken 1a894829f0 🎨 Search: Custom-button eksempel for aksel 2023-05-26 14:04:59 +02:00
Halvor Haugan e06a76b5c5 🐛 aksel-icons copyfiles-kommandoen fungerer nå på Win/Unix (#2007) 2023-05-25 22:35:49 +02:00
github-actions[bot]andgithub-actions[bot] 18d6f63e3e Version Packages (#2006)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-05-25 15:12:17 +02:00
Ken 4953e6725e 🐛 Ignore figma-plugin 2023-05-25 14:53:43 +02:00
Christian Skrøvseth 5533fbd5a3 Migrate CopyButton from deprecated to modern clipboard (#2005) 2023-05-25 14:40:22 +02:00
Ken 2c54cd077b 🎨 Icon-plugin (#1997) 2023-05-25 13:38:37 +02:00
Ken c84efa5ee9 🐛 Disable chromatic-snapshot av flaky button-story 2023-05-25 13:08:13 +02:00
Ken 9f3bcb8974 🐛 Endret rekkefølge på timeline-eksempler 2023-05-25 13:03:55 +02:00
github-actions[bot]andgithub-actions[bot] c8375ba46f Version Packages (#2002)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-05-25 12:36:22 +02:00
Ken 288cef591a Timeline viser popover på hover (#1995) 2023-05-25 12:25:26 +02:00
Ken aa3b4c22d6 🎨 Mulighet for manuell sortering av elementer i grunnleggende-sidebar 2023-05-24 18:26:38 +02:00
github-actions[bot]andgithub-actions[bot] 46af5defd9 Version Packages (#2001)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-05-24 15:32:35 +02:00
Ken 30eee0dac4 🐛 Fikset htmlSize-prop for <Search /> (#2000) 2023-05-24 14:36:34 +02:00
Ken 76b3a65572 Update README.md 2023-05-23 12:39:10 +02:00
github-actions[bot]andgithub-actions[bot] cb7a78e20c Version Packages (#1999)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-05-22 16:43:10 +02:00
Ken 475e994f49 🐛 DatepickerInput button refactor (#1993) 2023-05-22 16:36:33 +02:00
Ken 53c98181c3 🎨 Oppdatert ikoner (#1998) 2023-05-22 16:34:49 +02:00
Ken 444e905e01 🎨 xsmall variant for CopyButton (#1994) 2023-05-22 16:29:25 +02:00
Ken b7a97339f8 🚚 Flyttet Hva er aksel under 'Om nettstedet' i footer 2023-05-22 10:51:35 +02:00
Ken 1ac0f25420 ⬆️ Oppdatert sanity (#1992) 2023-05-22 09:09:11 +02:00
github-actions[bot]andgithub-actions[bot] 29ddcd59e7 Version Packages (#1990)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-05-19 09:47:18 +02:00
Ken 6d6267fe01 🔥 Fjernet use-client directive fra copybutton 2023-05-19 09:43:37 +02:00
Ken ee38a55837 🐛 Fikset tekst i internal-header 2023-05-16 14:22:30 +02:00
Ken b86ccc4f7f 🐛 Fikset aksel-eksempler 2023-05-16 13:24:02 +02:00
github-actions[bot]andgithub-actions[bot] 9a98f0eae4 Version Packages (#1988)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-05-16 13:13:56 +02:00
Ken affcab14c3 ✨ Copybutton-komponent (#1982) 2023-05-16 12:56:16 +02:00
Ken d51b0238d5 💄 Oppdatert ToggleGroup-bruk på ikonsider 2023-05-12 12:58:22 +02:00
github-actions[bot]andgithub-actions[bot] c818a92355 Version Packages (#1977)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-05-11 15:57:52 +02:00
Ken e8ecf309a9 💄 Oppdatert ToggleGroup (#1976) 2023-05-11 15:55:30 +02:00
Ken 060d4f3c7c 📝 Bedre props-dokumentasjon for ExpansionCard 2023-05-11 12:35:10 +02:00
github-actions[bot]andgithub-actions[bot] 1871038837 Version Packages (#1974)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-05-10 22:19:00 +02:00
Ken 5e79234eff 🐛 Timeline pin var ikke riktig alignet 2023-05-10 16:03:09 +02:00
github-actions[bot]andgithub-actions[bot] b8bebace11 Version Packages (#1971)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-05-10 14:10:55 +02:00
Ken 14379a02c3 🐛 Timeline håndterte ikke SVG-ikoner riktig 2023-05-10 13:56:20 +02:00
github-actions[bot]andgithub-actions[bot] d716ebbc40 Version Packages (#1970)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-05-10 13:33:21 +02:00
Ken f1c4c46ebb 💄 Focus-visible (#1966) 2023-05-10 13:04:29 +02:00
Ken 9d2cd9e7ff 💄 Oppdatert label/description for skjemakomponenter (#1967) 2023-05-10 12:54:29 +02:00
github-actions[bot]andgithub-actions[bot] 2fe5a0a0e2 Version Packages (#1968)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-05-10 10:22:48 +02:00
Ken db3846f5cd 🐛 Fikset default headingSize for button 2023-05-10 10:16:19 +02:00
Ken fa2ead912a 🔥 Fjernet ds-icons fra ds-react dependencies 2023-05-09 13:28:35 +02:00
Ken 11e9b9bef2 🐛 Fikset visning av kode under examples 2023-05-09 13:14:09 +02:00
github-actions[bot]andgithub-actions[bot] 6f53b33e69 Version Packages (#1965)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-05-09 13:05:15 +02:00
KenandJulian Nymark 166ee5feb3 ✨ V3, Accordion og ikonoppdatering (#1964)
Co-authored-by: Julian Nymark <j@juliannymark.com>
2023-05-09 12:06:35 +02:00
AndreasDybdahl c29d2aba1b Update ExpansionCardDescription.tsx (#1962) 2023-05-06 18:47:18 +02:00
github-actions[bot]andgithub-actions[bot] 2568fe70b1 Version Packages (#1960)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-05-05 10:18:28 +02:00
Ken 8790c5997e 💄 Statusikoner er nå tydeligere og mer konsistente. (#1959) 2023-05-05 10:13:24 +02:00
Ken 5b12778c96 🐛 CheckmarkIcon fix 2023-05-04 14:11:51 +02:00
github-actions[bot]andgithub-actions[bot] 3edb149b01 Version Packages (#1957)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-05-04 10:34:54 +02:00
Ken 8c85590099 🐛 CheckMarkCircle var ikke riktig alignet (#1956) 2023-05-04 10:31:38 +02:00
github-actions[bot]andgithub-actions[bot] 029d3c7719 Version Packages (#1955)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-05-03 16:00:48 +02:00
Ken 7019898c09 🐛 Timeline håndterte ikke startDate/endDate-endringer riktig (#1953) 2023-05-03 15:50:55 +02:00
github-actions[bot]andgithub-actions[bot] 36f4f5646a Version Packages (#1954)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-05-03 15:23:45 +02:00
Ken 27b2b4a11c 🚚 Flyttet codemods fra @navikt/ds-codemods -> @navikt/aksel (#1952) 2023-05-03 15:17:12 +02:00
Ken 9c0174e206 🎨 Ansvarlig for tema er nå opt-in for god-praksis 2023-05-03 12:23:55 +02:00
351 changed files with 12575 additions and 4261 deletions

No files matched your search

+8 -2
View File
@@ -13,14 +13,20 @@
"@navikt/ds-codemod",
"@navikt/aksel-icons",
"@navikt/aksel",
"@navikt/ds-icons"
"@navikt/ds-icons",
"@navikt/aksel-stylelint"
]
],
"linked": [],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": ["shadow-dom", "aksel.nav.no", "@navikt/ds-navno"],
"ignore": [
"shadow-dom",
"aksel.nav.no",
"@navikt/ds-navno",
"aksel-icons-figma-plugin"
],
"___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": {
"updateInternalDependents": "always"
+1 -1
View File
@@ -23,7 +23,7 @@ module.exports = {
addons: [
"@storybook/addon-a11y",
"@whitespace/storybook-addon-html",
"@storybook/addon-interactions",
{
name: "@storybook/addon-storysource",
options: {
+57
View File
@@ -1,5 +1,62 @@
# @navikt/aksel-icons
## 3.4.0
## 3.3.1
## 3.3.0
## 3.2.4
## 3.2.3
### Patch Changes
- [#1998](https://github.com/navikt/aksel/pull/1998) [`53c98181c`](https://github.com/navikt/aksel/commit/53c98181c327ead3406bec3487c10232af7d463a) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :tada: Nye ikoner!
- :sparkles: FileParagraph
- :sparkles: FilePlus
## 3.2.2
## 3.2.1
## 3.2.0
## 3.1.3
## 3.1.2
## 3.1.1
## 3.1.0
## 3.0.1
## 3.0.0
## 2.9.8
### Patch Changes
- [#1959](https://github.com/navikt/aksel/pull/1959) [`8790c5997`](https://github.com/navikt/aksel/commit/8790c5997e0d647419bdb5080c86781d08c196b8) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :lipstick: Statusikoner er nå tydeligere og mer konsistente.
## 2.9.7
### Patch Changes
- :bug: CheckmarkIcon
## 2.9.6
### Patch Changes
- [#1956](https://github.com/navikt/aksel/pull/1956) [`8c8559009`](https://github.com/navikt/aksel/commit/8c8559009982911bc4402913656ba4cc6a223dd1) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :bug: Fikset CheckmarkCircleIcon
## 2.9.5
## 2.9.4
## 2.9.3
### Patch Changes
+5
View File
@@ -24,6 +24,11 @@ fs.writeFileSync(
`const metadata = ${JSON.stringify(metadata)};\n\n module.exports = metadata;`
);
fs.writeFileSync(
path.resolve(__dirname, "../dist/metadata.mjs"),
`const metadata = ${JSON.stringify(metadata)};\n\n export default metadata;`
);
fs.writeFileSync(
path.resolve(__dirname, "../dist/metadata.d.ts"),
`export type AkselIcon = {
@@ -0,0 +1,26 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
!src
!*.d.ts
@@ -0,0 +1,22 @@
![](/src/assets/gh-cover.png)
# Aksel Icons plugin
Pluginen gir deg mulighet til å se gjennom og hente ut alle ikonene i fra ikonpakken `@navikt/aksel-icons`. Du slipper da å hente nye oppdateringer fra Figma Community.
Referer til [ikon-dokumentasjonen](https://aksel.nav.no/ikoner) for å se alle ikonene.
Har du ønsker om nye ikoner, eller ønsker å bidra med å lage nye, lag et issue på [GitHub-repoet for designsystemet](https://github.com/navikt/aksel).
## Quickstart
- `yarn dev` for development
- `yarn build` for production-build
### Test with Figma
- Open `Figma` -> `Plugins` -> `Development` -> `Import plugin from manifest...` and choose `manifest.json` file from this repo.
### Publish to Figma
- Open `Figma` -> `Plugins` -> `Find more plugins` -> `Publish new versions`
(requires publish-access)
@@ -0,0 +1,10 @@
{
"name": "Aksel Icons",
"id": "1221057403873975172",
"api": "1.0.0",
"main": "dist/plugin.js",
"ui": "dist/index.html",
"capabilities": [],
"enableProposedApi": false,
"editorType": ["figma", "figjam"]
}
@@ -0,0 +1,35 @@
{
"name": "aksel-icons-figma-plugin",
"private": true,
"version": "1.0.0",
"type": "module",
"scripts": {
"dev": "vite -c ./vite.config.ui.ts",
"build:icon-plugin": "tsc && npm run build:ui && npm run build:plugin",
"build:ui": "vite build -c ./vite.config.ui.ts --emptyOutDir",
"build:plugin": "vite build -c ./vite.config.plugin.ts",
"preview": "vite preview"
},
"dependencies": {
"@navikt/ds-css": "*",
"@navikt/ds-react": "*",
"fuse.js": "^6.6.2",
"react": "^18.0.0",
"react-dom": "^18.0.0"
},
"devDependencies": {
"@figma/plugin-typings": "^1.62.0",
"@svgr/core": "^6.5.1",
"@types/node": "^18.15.11",
"@types/postcss-url": "^10.0.0",
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"@vitejs/plugin-react": "^3.1.0",
"postcss": "^8.4.0",
"postcss-url": "^10.1.3",
"typescript": "^4.8.0",
"vite": "^4.2.0",
"vite-plugin-singlefile": "^0.13.3",
"vite-plugin-svgr": "^2.4.0"
}
}
@@ -0,0 +1,31 @@
/* eslint-disable import/no-anonymous-default-export */
import fs from "fs";
import { Plugin } from "vite";
function svgToDataURL(svgStr: string) {
const encoded = encodeURIComponent(svgStr)
.replace(/'/g, "%27")
.replace(/"/g, "%22");
const header = "data:image/svg+xml,";
const dataUrl = header + encoded;
return dataUrl;
}
export default function (): Plugin {
return {
name: "vite-inline-svg",
enforce: "pre",
async load(id) {
const [path, query] = id.split("?", 2);
if (!path.endsWith(".svg")) return;
if (query !== "inline") return;
const svg = await fs.promises.readFile(path, "utf-8");
return `export default "${svgToDataURL(svg)}"`;
},
};
}
@@ -0,0 +1,50 @@
import { createFilter, FilterPattern } from "@rollup/pluginutils";
import type { Config } from "@svgr/core";
import fs from "fs";
import type { Plugin } from "vite";
import { transformWithEsbuild } from "vite";
export interface ViteSvgrOptions {
svgrOptions?: Config;
esbuildOptions?: Parameters<typeof transformWithEsbuild>[2];
exclude?: FilterPattern;
include?: FilterPattern;
}
export default function viteSvgr({
svgrOptions,
esbuildOptions,
include = "**/*.svg?component",
exclude,
}: ViteSvgrOptions = {}): Plugin {
const filter = createFilter(include, exclude);
return {
name: "vite-svgr-component",
async transform(code, id) {
if (filter(id)) {
const { transform } = await import("@svgr/core");
const svgCode = await fs.promises.readFile(
id.replace(/\?.*$/, ""),
"utf8"
);
const componentCode = await transform(svgCode, svgrOptions, {
filePath: id,
caller: { previousExport: null },
});
const res = await transformWithEsbuild(componentCode, id, {
loader: "jsx",
...esbuildOptions,
});
return {
code: res.code,
map: null,
};
}
},
};
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

@@ -0,0 +1,4 @@
<svg width="32" height="32" viewBox="0 0 170 170" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.07318 54.5734C-0.692218 51.806 -0.690888 47.3204 2.07614 44.5546L38.6019 8.04512C38.7787 7.8684 38.9576 7.69433 39.1387 7.52295L39.1205 7.50476C42.7235 3.90124 47.1588 1.63753 51.8075 0.71364C53.8316 0.243049 55.9182 1.07479e-05 58.0297 1.01387e-05L142.517 0C157.695 5.55246e-06 170 12.3065 170 27.4874V111.958C170 113.916 169.791 115.852 169.386 117.737C168.522 122.523 166.241 127.103 162.542 130.803L162.533 130.794C162.342 130.997 162.148 131.197 161.95 131.395L125.425 167.925C122.659 170.692 118.174 170.692 115.408 167.925C112.642 165.158 112.642 160.673 115.408 157.906L151.933 121.376C153.698 119.61 154.917 117.4 155.48 115.008C155.999 111.779 155.014 108.355 152.525 105.866L64.1955 17.5236C61.632 14.9597 58.0865 13.9765 54.7698 14.574C52.4605 15.1572 50.3292 16.3547 48.6162 18.0669L12.0905 54.5764C9.32349 57.3422 4.83857 57.3409 2.07318 54.5734ZM80.8759 14.1688L155.833 89.1374V27.4874C155.833 20.1317 149.871 14.1688 142.517 14.1688L80.8759 14.1688Z" fill="#004367"/>
<path d="M2.07466 167.925C-0.691554 165.158 -0.691554 160.673 2.07466 157.906L65.8247 94.1468C68.5909 91.3801 73.0758 91.3801 75.842 94.1468C78.6082 96.9134 78.6082 101.399 75.842 104.166L12.092 167.925C9.32579 170.692 4.84087 170.692 2.07466 167.925Z" fill="#004367"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

@@ -0,0 +1,21 @@
/* eslint-disable no-restricted-globals */
/* eslint-disable no-undef */
import * as Networker from "monorepo-networker";
import { NetworkMessages } from "@common/network/messages";
import { NetworkSide } from "@common/network/sides";
export const initializeNetwork = Networker.createInitializer({
messagesRegistry: NetworkMessages.registry,
initTransports: function (register) {
register(NetworkSide.PLUGIN, NetworkSide.UI, (message) => {
// @ts-ignore
figma.ui.postMessage(message);
});
register(NetworkSide.UI, NetworkSide.PLUGIN, (message) => {
// @ts-ignore
parent.postMessage({ pluginMessage: message }, "*");
});
},
});
@@ -0,0 +1,21 @@
import { CreateRectMessage } from "@common/network/messages/CreateRectMessage";
import { HelloMessage } from "@common/network/messages/HelloMessage";
import { PingMessage } from "@common/network/messages/PingMessage";
import { NetworkSide } from "@common/network/sides";
import * as Networker from "monorepo-networker";
export namespace NetworkMessages {
export const registry = new Networker.MessageTypeRegistry();
export const PING = registry.register(new PingMessage("ping"));
export const HELLO_PLUGIN = registry.register(
new HelloMessage(NetworkSide.PLUGIN)
);
export const HELLO_UI = registry.register(new HelloMessage(NetworkSide.UI));
export const CREATE_RECT = registry.register(
new CreateRectMessage("create-rect")
);
}
@@ -0,0 +1,42 @@
/* eslint-disable no-undef */
import { NetworkSide } from "@common/network/sides";
import * as Networker from "monorepo-networker";
interface Payload {
width: number;
height: number;
}
export class CreateRectMessage extends Networker.MessageType<Payload> {
public receivingSide(): Networker.Side {
return NetworkSide.PLUGIN;
}
public handle(payload: Payload, from: Networker.Side): void {
// @ts-ignore
if (figma.editorType === "figma") {
// @ts-ignore
const rect = figma.createRectangle();
rect.x = 0;
rect.y = 0;
rect.name = "Plugin Rectangle # " + Math.floor(Math.random() * 9999);
rect.fills = [
{
type: "SOLID",
color: {
r: Math.random(),
g: Math.random(),
b: Math.random(),
},
},
];
rect.resize(payload.width, payload.height);
// @ts-ignore
figma.currentPage.appendChild(rect);
// @ts-ignore
figma.viewport.scrollAndZoomIntoView([rect]);
// @ts-ignore
figma.closePlugin();
}
}
}
@@ -0,0 +1,19 @@
import * as Networker from "monorepo-networker";
interface Payload {
text: string;
}
export class HelloMessage extends Networker.MessageType<Payload> {
constructor(private side: Networker.Side) {
super("hello-" + side.getName());
}
receivingSide(): Networker.Side {
return this.side;
}
handle(payload: Payload, from: Networker.Side) {
console.log(`${from.getName()} said "${payload.text}"`);
}
}
@@ -0,0 +1,17 @@
import * as Networker from "monorepo-networker";
import { NetworkSide } from "@common/network/sides";
interface Payload {}
type Response = string;
export class PingMessage extends Networker.MessageType<Payload, Response> {
receivingSide(): Networker.Side {
return NetworkSide.PLUGIN;
}
handle(payload: Payload, from: Networker.Side): string {
console.log(from.getName(), "has pinged us!");
return `Pong, ${from.getName()}!`;
}
}
@@ -0,0 +1,24 @@
/* eslint-disable no-undef */
import * as Networker from "monorepo-networker";
export namespace NetworkSide {
export const PLUGIN = Networker.Side.register(
new Networker.Side<MessageEvent<any>>("Plugin", {
// @ts-ignore
attachListener: (callback) => figma.ui.on("message", callback),
// @ts-ignore
detachListener: (callback) => figma.ui.off("message", callback),
})
);
export const UI = Networker.Side.register(
new Networker.Side("UI", {
shouldHandle: (event) => event.data?.pluginId != null,
messageGetter: (event) => event.data.pluginMessage,
attachListener: (callback) =>
window.addEventListener("message", callback),
detachListener: (callback) =>
window.removeEventListener("message", callback),
})
);
}
@@ -0,0 +1,48 @@
/* eslint-disable no-undef */
figma.showUI(__html__, { width: 480, height: 600 });
figma.ui.onmessage = (msg) => {
if (msg.type === "create-icon") {
const nodes = [];
const icon = figma.createNodeFromSvg(msg.svg);
icon.name = msg.name;
icon.resize(msg.size, msg.size);
nodes.push(icon);
figma.currentPage.appendChild(icon);
figma.viewport.scrollAndZoomIntoView(nodes);
figma.ui.postMessage({
type: "create-icon",
message: `Created ${msg.name} icon}`,
});
}
};
// https://github.com/figma/plugin-samples#icon-drag-and-drop
figma.on("drop", (event) => {
const { files, node } = event;
if (files.length > 0 && files[0].type === "image/svg+xml") {
files[0].getTextAsync().then((text) => {
const newNode = figma.createNodeFromSvg(text);
newNode.name = `${files[0].name.replace(".svg", "")}Icon`;
newNode.resize(24, 24);
// We can only append page nodes to documents
if ("appendChild" in node && node.type !== "DOCUMENT") {
node.appendChild(newNode);
}
newNode.x = event.x;
newNode.y = event.y;
figma.currentPage.selection = [newNode];
});
return false;
}
});
@@ -0,0 +1,193 @@
import { Heading, Search, ToggleGroup } from "@navikt/ds-react";
import Fuse from "fuse.js";
import { useEffect, useMemo, useState } from "react";
import * as Icons from "../../../";
import meta from "../../../dist/metadata";
import "./app.css";
import { categorizeIcons, getFillIcon } from "./utils";
const fuseStroke = new Fuse(
Object.values(meta).filter((x) => x.variant.toLowerCase() === "stroke"),
{
threshold: 0.2,
keys: [
{ name: "name", weight: 3 },
{ name: "category", weight: 2 },
{ name: "sub_category", weight: 2 },
{ name: "keywords", weight: 3 },
{ name: "variant", weight: 1 },
],
shouldSort: false,
}
);
const fuseFill = new Fuse(getFillIcon(Object.values(meta)), {
threshold: 0.2,
keys: [
{ name: "name", weight: 3 },
{ name: "category", weight: 2 },
{ name: "sub_category", weight: 2 },
{ name: "keywords", weight: 3 },
{ name: "variant", weight: 1 },
],
shouldSort: false,
});
const App = () => {
const [query, setQuery] = useState("");
const [toggle, setToggle] = useState<"stroke" | "fill">("stroke");
const [strokeIcons] = useState(
Object.values(meta).filter((x) => x.variant.toLowerCase() === "stroke")
);
const [fillIcons] = useState(getFillIcon(Object.values(meta)));
const categories = useMemo(() => {
if (toggle === "fill") {
return categorizeIcons(
query
? fuseFill.search(query).map((result) => result.item as any)
: fillIcons
);
}
return categorizeIcons(
query
? fuseStroke.search(query).map((result) => result.item as any)
: strokeIcons
);
}, [toggle, query, strokeIcons, fillIcons]);
const onCreate = (id: string, name: string) => {
let svg = document.getElementById(id)?.outerHTML;
let size = 24;
// eslint-disable-next-line no-restricted-globals
parent.postMessage(
{
pluginMessage: {
type: "create-icon",
svg,
size,
name,
},
},
"*"
);
};
useEffect(() => {
const dragEvent = (e) => {
// Don't proceed if the item was dropped inside the plugin window.
if (e.view.length === 0) {
return;
}
const file = new File([e.target.innerHTML], `${e.target.id}.svg`, {
type: "image/svg+xml",
});
window.parent.postMessage(
{
pluginDrop: {
clientX: e.clientX,
clientY: e.clientY,
files: [file],
name: e.target.id,
},
},
"*"
);
};
const icons = document.getElementsByClassName("icon-classname");
for (const icon of icons) {
icon.addEventListener("dragend", dragEvent);
}
return () => {
for (const icon of icons) {
icon.removeEventListener("dragend", dragEvent);
}
};
}, [categories]);
return (
<main tabIndex={-1} className="wrapper">
<form onSubmit={(e) => e.preventDefault()} className="form">
<div className="form-togglegroup">
<ToggleGroup
value={toggle}
onChange={(v) => setToggle(v as any)}
variant="neutral"
>
<ToggleGroup.Item value="stroke">Stroke</ToggleGroup.Item>
<ToggleGroup.Item value="fill">Fill</ToggleGroup.Item>
</ToggleGroup>
</div>
<div className="form-search">
<Search
variant="simple"
label="Ikonsøk"
style={{ border: "none" }}
placeholder="Søk"
autoComplete="off"
onChange={setQuery}
value={query}
clearButton={false}
/>
</div>
</form>
<div className="categories">
{categories.map((cat) => {
return (
<div key={cat.category}>
<Heading level="2" size="small" spacing>
{cat.category}
</Heading>
<div className="sub-categories">
{cat.sub_categories.map((sub) => {
return (
<div key={sub.sub_category}>
<Heading level="3" size="xsmall" className="sub-heading">
{sub.sub_category}
</Heading>
<div className="icons-wrapper">
{sub.icons.map((i) => {
const T = Icons[`${i.id}Icon`];
if (T === undefined) {
console.log(i);
return null;
}
return (
<button
key={i.id}
id={i.id}
onClick={() => {
onCreate(`icon-id-${i.id}`, `${i.id}Icon`);
}}
draggable="true"
className="icon-classname icon-button"
>
<T
font-size="2rem"
title={i.id}
id={`icon-id-${i.id}`}
/>
</button>
);
})}
</div>
</div>
);
})}
</div>
</div>
);
})}
</div>
</main>
);
};
export default App;
@@ -0,0 +1,79 @@
@import "@navikt/ds-css";
.wrapper {
background-color: var(--a-bg-default);
}
.form {
border-bottom: 1px solid var(--a-border-subtle);
position: sticky;
top: 0;
z-index: 20;
display: flex;
align-items: center;
height: fit-content;
width: 100%;
gap: 1rem;
padding-block: 0.5rem;
padding-inline: 1rem;
background-color: var(--a-bg-default);
}
.form-togglegroup {
min-width: 10rem;
}
.form-search {
display: flex;
gap: 0.5rem;
align-items: center;
width: 100%;
}
.categories {
display: grid;
width: 100%;
place-content: start;
gap: 2rem;
padding: 1.5rem;
}
.sub-categories {
display: grid;
width: 100%;
gap: 0.5rem;
}
.sub-heading {
color: var(--a-text-subtle);
margin-bottom: 0.25rem;
}
.icons-wrapper {
gap: 0.125rem;
display: flex;
flex-wrap: wrap;
}
.icon-button {
min-height: 3rem;
min-width: 3rem;
border-radius: 2px;
display: grid;
place-content: center;
background-color: var(--a-surface-default);
cursor: pointer;
border: none;
}
.icon-button:hover {
background-color: var(--a-surface-hover);
}
.icon-button:active {
background-color: var(--a-surface-neutral-subtle-hover);
}
.icon-button:focus-visible {
outline: 2px solid var(--a-border-focus);
}
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Aksel icons</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="./main.tsx"></script>
</body>
</html>
@@ -0,0 +1,9 @@
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
@@ -0,0 +1,56 @@
import meta from "@navikt/aksel-icons/metadata";
const subCategorizeIcons = (
icons: typeof meta[1][]
): { sub_category: string; icons: typeof meta[1][] }[] => {
const categories: { sub_category: string; icons: typeof meta[1][] }[] = [];
for (const icon of icons) {
const i = categories.findIndex(
({ sub_category }) => icon.sub_category === sub_category
);
i !== -1
? categories[i].icons.push(icon)
: categories.push({ sub_category: icon.sub_category, icons: [icon] });
}
return categories.sort((a, b) =>
a.sub_category.localeCompare(b.sub_category)
);
};
export const categorizeIcons = (
icons: typeof meta[1][]
): {
category: string;
sub_categories: { sub_category: string; icons: typeof meta[1][] }[];
}[] => {
const categories: {
category: string;
icons: typeof meta[1][];
}[] = [];
for (const icon of icons) {
const i = categories.findIndex(
({ category }) => icon.category === category
);
i !== -1
? categories[i].icons.push(icon)
: categories.push({ category: icon.category, icons: [icon] });
}
return categories
.sort((a, b) => a.category.localeCompare(b.category))
.map((x) => ({ ...x, sub_categories: subCategorizeIcons(x.icons) }));
};
const noFill = (icon: typeof meta[1], icons: typeof meta[1][]) => {
const foundFill = icons.find(
(x) => x.name.endsWith("Fill") && x.name.replace("Fill", "") === icon.name
);
return !foundFill;
};
export const getFillIcon = (icons: typeof meta[1][]) => {
return icons.filter(
(x, _, z) => x.variant.toLowerCase() === "fill" || noFill(x, z)
);
};
+30
View File
@@ -0,0 +1,30 @@
/// <reference types="vite/client" />
declare module "*.svg?component" {
import * as React from "react";
const ReactComponent: React.FunctionComponent<
React.ComponentProps<"svg"> & { title?: string }
>;
export default ReactComponent;
}
declare module "**/metadata.mjs" {
export type AkselIcon = {
id: string;
name: string;
category: string;
sub_category: "Time";
keywords: string[];
variant: "stroke" | "fill";
updated_at: Date;
created_at: Date;
};
declare const metadata: {
[iconId: string]: AkselIcon;
};
export default metadata;
}
@@ -0,0 +1,30 @@
{
"compilerOptions": {
"target": "ESNext",
"module": "CommonJS",
"allowJs": false,
"skipLibCheck": true,
"esModuleInterop": true,
"moduleResolution": "Node",
"resolveJsonModule": true,
"isolatedModules": false,
"noEmit": true,
"jsx": "react-jsx",
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"rootDir": ".",
"baseUrl": ".",
"outDir": "dist/",
"sourceMap": false,
"noImplicitAny": false,
"types": ["@figma/plugin-typings"]
},
"include": [
"src/**/*.d.ts",
"src/**/*.d.ts",
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.js",
"src/**/*.jsx"
],
"exclude": ["src/common/**/*"]
}
@@ -0,0 +1,13 @@
{
"compilerOptions": {
"composite": true,
"module": "ESNext",
"moduleResolution": "Node",
"allowSyntheticDefaultImports": true
},
"include": [
"vite.config.plugin.ts",
"vite.config.ui.ts",
"./scripts/vite/*.ts"
]
}
@@ -0,0 +1,17 @@
import path from "path";
import { defineConfig } from "vite";
import { viteSingleFile } from "vite-plugin-singlefile";
export default defineConfig({
plugins: [viteSingleFile()],
build: {
lib: {
name: "Aksel Icons",
entry: path.resolve(__dirname, "./src/plugin/plugin.ts"),
fileName: "plugin",
formats: ["es"],
},
emptyOutDir: false,
outDir: path.resolve(__dirname, "./dist"),
},
});
@@ -0,0 +1,25 @@
import { defineConfig } from "vite";
import path from "path";
import { viteSingleFile } from "vite-plugin-singlefile";
import react from "@vitejs/plugin-react";
import inlineSvg from "./scripts/vite/vite-inline-svg";
import svgComponent from "./scripts/vite/vite-svgr-component";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react(), svgComponent(), inlineSvg(), viteSingleFile()],
root: path.resolve(__dirname, "./src/ui/"),
build: {
outDir: path.resolve(__dirname, "./dist"),
rollupOptions: {
input: {
ui: path.relative(__dirname, "./src/ui/index.html"),
},
output: {
entryFileNames: "[name].js",
},
},
},
});
+1 -1
View File
@@ -15,5 +15,5 @@ keywords:
- skråning
- helning
variant: Stroke
updated_at: 08.03.2023
updated_at: 22.05.2023
created_at: 07.03.2023
+1 -1
View File
@@ -1,3 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M19.0303 6.96967C19.3232 7.26256 19.3232 7.73744 19.0303 8.03033L10.5303 16.5303C10.2374 16.8232 9.76256 16.8232 9.46967 16.5303L4.96967 12.0303C4.67678 11.7374 4.67678 11.2626 4.96967 10.9697C5.26256 10.6768 5.73744 10.6768 6.03033 10.9697L10 14.9393L17.9697 6.96967C18.2626 6.67678 18.7374 6.67678 19.0303 6.96967Z" fill="#262626"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M18.9983 6.93942C19.3079 7.21461 19.3357 7.68866 19.0606 7.99825L11.0606 16.9983C10.9233 17.1526 10.7285 17.2436 10.522 17.2497C10.3156 17.2557 10.1157 17.1764 9.96967 17.0303L4.96967 12.0303C4.67678 11.7374 4.67678 11.2625 4.96967 10.9696C5.26256 10.6768 5.73744 10.6768 6.03033 10.9696L10.4679 15.4072L17.9394 7.0017C18.2146 6.69212 18.6887 6.66423 18.9983 6.93942Z" fill="#262626"/>
</svg>

Before

Width:  |  Height:  |  Size: 487 B

After

Width:  |  Height:  |  Size: 538 B

+1 -1
View File
@@ -15,5 +15,5 @@ keywords:
- fullføring
- validering
variant: Stroke
updated_at: 14.04.2023
updated_at: 04.05.2023
created_at: 07.03.2023
@@ -15,5 +15,5 @@ keywords:
- fullføring
- validering
variant: Stroke
updated_at: 08.03.2023
updated_at: 04.05.2023
created_at: 07.03.2023
@@ -1,3 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21ZM16.5725 9.48447C16.8401 9.16827 16.8007 8.69503 16.4845 8.42748C16.1683 8.15992 15.695 8.19935 15.4275 8.51556L10.454 14.3933L8.03033 11.9697C7.73744 11.6768 7.26256 11.6768 6.96967 11.9697C6.67678 12.2626 6.67678 12.7375 6.96967 13.0303L9.96967 16.0303C10.118 16.1787 10.3216 16.2581 10.5312 16.2494C10.7407 16.2407 10.9371 16.1446 11.0725 15.9845L16.5725 9.48447Z" fill="#262626"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 21.75C17.3848 21.75 21.75 17.3848 21.75 12C21.75 6.61522 17.3848 2.25 12 2.25C6.61522 2.25 2.25 6.61522 2.25 12C2.25 17.3848 6.61522 21.75 12 21.75ZM16.9536 9.27485C17.2434 8.93229 17.2007 8.41962 16.8582 8.12977C16.5156 7.83991 16.0029 7.88263 15.7131 8.22519L10.3251 14.5928L7.69952 11.9672C7.38222 11.6499 6.86778 11.6499 6.55048 11.9672C6.23317 12.2845 6.23317 12.7989 6.55048 13.1162L9.80048 16.3662C9.96114 16.5269 10.1817 16.6129 10.4088 16.6035C10.6358 16.594 10.8485 16.49 10.9953 16.3165L16.9536 9.27485Z" fill="#262626"/>
</svg>

Before

Width:  |  Height:  |  Size: 650 B

After

Width:  |  Height:  |  Size: 689 B

@@ -15,5 +15,5 @@ keywords:
- fullføring
- validering
variant: Fill
updated_at: 08.03.2023
updated_at: 04.05.2023
created_at: 07.03.2023
+1 -1
View File
@@ -9,5 +9,5 @@ keywords:
- vise/skjule
- bytte
variant: Stroke
updated_at: 08.03.2023
updated_at: 02.05.2023
created_at: 07.03.2023
+1 -1
View File
@@ -10,5 +10,5 @@ keywords:
- nettverk
- network
variant: Stroke
updated_at: 18.04.2023
updated_at: 04.05.2023
created_at: 07.03.2023
@@ -11,5 +11,5 @@ keywords:
- handel
- økonomi
variant: Stroke
updated_at: 08.03.2023
updated_at: 16.05.2023
created_at: 07.03.2023
@@ -13,5 +13,5 @@ keywords:
- oppmerksomhet
- viktig
variant: Stroke
updated_at: 25.04.2023
updated_at: 04.05.2023
created_at: 07.03.2023
+1 -1
View File
@@ -7,5 +7,5 @@ keywords:
- lukket
- hidden
variant: Stroke
updated_at: 08.03.2023
updated_at: 05.05.2023
created_at: 07.03.2023
@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.75 4.75V19.25H17.25V8.75H14.5C13.8096 8.75 13.25 8.19036 13.25 7.5V4.75H6.75ZM14.75 5.81066L16.1893 7.25H14.75V5.81066ZM5.25 4.5C5.25 3.80964 5.80964 3.25 6.5 3.25H14C14.1989 3.25 14.3897 3.32902 14.5303 3.46967L18.5303 7.46967C18.671 7.61032 18.75 7.80109 18.75 8V19.5C18.75 20.1904 18.1904 20.75 17.5 20.75H6.5C5.80964 20.75 5.25 20.1904 5.25 19.5V4.5ZM9.96599 11.0256C9.96599 9.906 10.8749 9 11.9927 9C12.5664 9 13.0857 9.23917 13.4539 9.62112C13.7414 9.91932 13.7327 10.3941 13.4345 10.6816C13.1363 10.9691 12.6615 10.9604 12.3741 10.6622C12.2767 10.5613 12.1424 10.5 11.9927 10.5C11.7016 10.5 11.466 10.7362 11.466 11.0256C11.466 11.2386 11.5945 11.4305 11.7915 11.5116L13.7023 12.2984C14.5828 12.661 15.039 13.6373 14.7523 14.5454C14.6107 14.9939 14.3133 15.3485 13.9395 15.57C13.9933 15.7527 14.0218 15.9449 14.0218 16.1418C14.0218 17.2614 13.1128 18.1674 11.995 18.1674C11.0546 18.1674 10.264 17.5278 10.0337 16.6602C9.92739 16.2599 10.1658 15.8492 10.5661 15.7429C10.9665 15.6366 11.3772 15.875 11.4835 16.2753C11.5434 16.5012 11.7509 16.6674 11.995 16.6674C12.2862 16.6674 12.5218 16.4312 12.5218 16.1418C12.5218 15.9288 12.3932 15.7369 12.1963 15.6558L10.2855 14.869C9.40497 14.5065 8.9487 13.5301 9.23544 12.6221C9.37709 12.1735 9.67447 11.8189 10.0483 11.5974C9.99448 11.4147 9.96599 11.2225 9.96599 11.0256ZM10.8566 13.482L12.6473 14.2194C12.6562 14.2222 12.6651 14.2252 12.6739 14.2284L12.8915 14.3067C13.0695 14.3708 13.265 14.274 13.3219 14.0937C13.374 13.9287 13.2911 13.7513 13.1311 13.6854L11.3404 12.9481C11.3315 12.9452 11.3227 12.9422 11.3138 12.939L11.0962 12.8607C10.9183 12.7966 10.7228 12.8934 10.6658 13.0738C10.6137 13.2387 10.6966 13.4161 10.8566 13.482Z" fill="#262626"/>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

@@ -0,0 +1,17 @@
name: FileParagraph
category: Files and application
sub_category: Files
keywords:
- document
- dokument
- fil
- file
- error
- feil
- feilmelding
- corrupt
- bad file
- korrupt fil
variant: Stroke
updated_at: 22.05.2023
created_at: 22.05.2023
@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.25 7.5V3.5C13.25 3.36193 13.1381 3.25 13 3.25H6.5C5.80964 3.25 5.25 3.80964 5.25 4.5V19.5C5.25 20.1904 5.80964 20.75 6.5 20.75H17.5C18.1904 20.75 18.75 20.1904 18.75 19.5V9C18.75 8.86193 18.6381 8.75 18.5 8.75H14.5C13.8096 8.75 13.25 8.19036 13.25 7.5ZM15 7.25C14.8619 7.25 14.75 7.13807 14.75 7V4.29289C14.75 4.07017 15.0193 3.95863 15.1768 4.11612L17.8839 6.82322C18.0414 6.98071 17.9298 7.25 17.7071 7.25H15ZM9.96599 11.0256C9.96599 9.906 10.8749 9 11.9927 9C12.5664 9 13.0857 9.23917 13.4539 9.62112C13.7414 9.91932 13.7327 10.3941 13.4345 10.6816C13.1363 10.9691 12.6615 10.9604 12.3741 10.6622C12.2767 10.5613 12.1424 10.5 11.9927 10.5C11.7016 10.5 11.466 10.7362 11.466 11.0256C11.466 11.2386 11.5945 11.4305 11.7915 11.5116L13.7023 12.2984C14.5828 12.661 15.039 13.6373 14.7523 14.5454C14.6318 14.927 14.3985 15.2407 14.1012 15.4622C14.0095 15.5306 13.9637 15.6466 13.9853 15.7589C14.0093 15.8836 14.0218 16.0117 14.0218 16.1418C14.0218 17.2614 13.1128 18.1674 11.995 18.1674C11.0546 18.1674 10.264 17.5278 10.0337 16.6602C9.92739 16.2599 10.1658 15.8492 10.5661 15.7429C10.9665 15.6366 11.3772 15.875 11.4835 16.2753C11.5434 16.5012 11.7509 16.6674 11.995 16.6674C12.2862 16.6674 12.5218 16.4312 12.5218 16.1418C12.5218 15.9288 12.3932 15.7369 12.1963 15.6558L10.2855 14.869C9.40497 14.5065 8.9487 13.5301 9.23544 12.6221C9.35598 12.2404 9.58928 11.9267 9.8865 11.7052C9.97822 11.6368 10.024 11.5208 10.0024 11.4085C9.97844 11.2838 9.96599 11.1557 9.96599 11.0256ZM10.8566 13.482L12.6473 14.2194C12.6562 14.2222 12.6651 14.2252 12.6739 14.2284L12.8915 14.3067C13.0695 14.3708 13.265 14.274 13.3219 14.0937C13.374 13.9287 13.2911 13.7513 13.1311 13.6854L11.3404 12.9481C11.3315 12.9452 11.3227 12.9422 11.3138 12.939L11.0962 12.8607C10.9183 12.7966 10.7228 12.8934 10.6658 13.0738C10.6137 13.2387 10.6966 13.4161 10.8566 13.482Z" fill="#262626"/>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

@@ -0,0 +1,17 @@
name: FileParagraphFill
category: Files and application
sub_category: Files
keywords:
- document
- dokument
- fil
- file
- error
- feil
- feilmelding
- corrupt
- bad file
- korrupt fil
variant: Fill
updated_at: 22.05.2023
created_at: 22.05.2023
+3
View File
@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.75 19.25V4.75H13.25V7.5C13.25 8.19036 13.8096 8.75 14.5 8.75H17.25V19.25H6.75ZM16.1893 7.25L14.75 5.81066V7.25H16.1893ZM6.5 3.25C5.80964 3.25 5.25 3.80964 5.25 4.5V19.5C5.25 20.1904 5.80964 20.75 6.5 20.75H17.5C18.1904 20.75 18.75 20.1904 18.75 19.5V8C18.75 7.80109 18.671 7.61032 18.5303 7.46967L14.5303 3.46967C14.3897 3.32902 14.1989 3.25 14 3.25H6.5ZM9.12868 14C9.12868 13.5858 9.46447 13.25 9.87868 13.25H11.25V11.8787C11.25 11.4645 11.5858 11.1287 12 11.1287C12.4142 11.1287 12.75 11.4645 12.75 11.8787V13.25H14.1213C14.5355 13.25 14.8713 13.5858 14.8713 14C14.8713 14.4142 14.5355 14.75 14.1213 14.75H12.75V16.1213C12.75 16.5355 12.4142 16.8713 12 16.8713C11.5858 16.8713 11.25 16.5355 11.25 16.1213V14.75H9.87868C9.46447 14.75 9.12868 14.4142 9.12868 14Z" fill="#262626"/>
</svg>

After

Width:  |  Height:  |  Size: 936 B

+17
View File
@@ -0,0 +1,17 @@
name: FilePlus
category: Files and application
sub_category: Files
keywords:
- document
- dokument
- fil
- file
- error
- feil
- feilmelding
- corrupt
- bad file
- korrupt fil
variant: Stroke
updated_at: 22.05.2023
created_at: 22.05.2023
@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.25 7.5V3.5C13.25 3.36193 13.1381 3.25 13 3.25H6.5C5.80964 3.25 5.25 3.80964 5.25 4.5V19.5C5.25 20.1904 5.80964 20.75 6.5 20.75H17.5C18.1904 20.75 18.75 20.1904 18.75 19.5V9C18.75 8.86193 18.6381 8.75 18.5 8.75H14.5C13.8096 8.75 13.25 8.19036 13.25 7.5ZM15 7.25C14.8619 7.25 14.75 7.13807 14.75 7V4.29289C14.75 4.07017 15.0193 3.95863 15.1768 4.11612L17.8839 6.82322C18.0414 6.98071 17.9298 7.25 17.7071 7.25H15ZM12.0001 11.1287C12.4143 11.1287 12.7501 11.4645 12.7501 11.8787V13C12.7501 13.1381 12.862 13.25 13.0001 13.25H14.1214C14.5356 13.25 14.8714 13.5858 14.8714 14C14.8714 14.4142 14.5356 14.75 14.1214 14.75H13.0001C12.862 14.75 12.7501 14.8619 12.7501 15V16.1213C12.7501 16.5355 12.4143 16.8713 12.0001 16.8713C11.5858 16.8713 11.2501 16.5355 11.2501 16.1213V15C11.2501 14.8619 11.1381 14.75 11.0001 14.75H9.87874C9.46453 14.75 9.12874 14.4142 9.12874 14C9.12874 13.5858 9.46453 13.25 9.87874 13.25H11.0001C11.1381 13.25 11.2501 13.1381 11.2501 13V11.8787C11.2501 11.4645 11.5858 11.1287 12.0001 11.1287Z" fill="#262626"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -0,0 +1,17 @@
name: FilePlusFill
category: Files and application
sub_category: Files
keywords:
- document
- dokument
- fil
- file
- error
- feil
- feilmelding
- corrupt
- bad file
- korrupt fil
variant: Fill
updated_at: 22.05.2023
created_at: 22.05.2023
+1 -1
View File
@@ -15,5 +15,5 @@ keywords:
- beskrivelse
- forklaring
variant: Stroke
updated_at: 31.03.2023
updated_at: 04.05.2023
created_at: 07.03.2023
@@ -1,3 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 3.25C3.58579 3.25 3.25 3.58579 3.25 4V20C3.25 20.4142 3.58579 20.75 4 20.75H20C20.4142 20.75 20.75 20.4142 20.75 20V4C20.75 3.58579 20.4142 3.25 20 3.25H4ZM4.75 19.25V4.75H19.25V19.25H4.75ZM12 7C11.4477 7 11 7.44772 11 8C11 8.55228 11.4477 9 12 9C12.5523 9 13 8.55228 13 8C13 7.44772 12.5523 7 12 7ZM10.5 10.25C10.0858 10.25 9.75 10.5858 9.75 11C9.75 11.4142 10.0858 11.75 10.5 11.75H11.25V15.75H10.5C10.0858 15.75 9.75 16.0858 9.75 16.5C9.75 16.9142 10.0858 17.25 10.5 17.25H12H13.5C13.9142 17.25 14.25 16.9142 14.25 16.5C14.25 16.0858 13.9142 15.75 13.5 15.75H12.75V11C12.75 10.5858 12.4142 10.25 12 10.25H10.5Z" fill="#262626"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 3.25C3.58579 3.25 3.25 3.58579 3.25 4V20C3.25 20.4142 3.58579 20.75 4 20.75H20C20.4142 20.75 20.75 20.4142 20.75 20V4C20.75 3.58579 20.4142 3.25 20 3.25H4ZM4.75 19.25V4.75H19.25V19.25H4.75ZM12 6.75C11.4477 6.75 11 7.19772 11 7.75C11 8.30228 11.4477 8.75 12 8.75C12.5523 8.75 13 8.30228 13 7.75C13 7.19772 12.5523 6.75 12 6.75ZM10.5 10C10.0858 10 9.75 10.3358 9.75 10.75C9.75 11.1642 10.0858 11.5 10.5 11.5H11.25V15.5H10.5C10.0858 15.5 9.75 15.8358 9.75 16.25C9.75 16.6642 10.0858 17 10.5 17H12H13.5C13.9142 17 14.25 16.6642 14.25 16.25C14.25 15.8358 13.9142 15.5 13.5 15.5H12.75V10.75C12.75 10.3358 12.4142 10 12 10H10.5Z" fill="#262626"/>
</svg>

Before

Width:  |  Height:  |  Size: 787 B

After

Width:  |  Height:  |  Size: 795 B

@@ -1,3 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.25 4C3.25 3.58579 3.58579 3.25 4 3.25H20C20.4142 3.25 20.75 3.58579 20.75 4V20C20.75 20.4142 20.4142 20.75 20 20.75H4C3.58579 20.75 3.25 20.4142 3.25 20V4ZM11 8C11 7.44772 11.4477 7 12 7C12.5523 7 13 7.44772 13 8C13 8.55228 12.5523 9 12 9C11.4477 9 11 8.55228 11 8ZM9.75 11C9.75 10.5858 10.0858 10.25 10.5 10.25H12C12.4142 10.25 12.75 10.5858 12.75 11V15.75H13.5C13.9142 15.75 14.25 16.0858 14.25 16.5C14.25 16.9142 13.9142 17.25 13.5 17.25H12H10.5C10.0858 17.25 9.75 16.9142 9.75 16.5C9.75 16.0858 10.0858 15.75 10.5 15.75H11.25V11.75H10.5C10.0858 11.75 9.75 11.4142 9.75 11Z" fill="#262626"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.25 4C3.25 3.58579 3.58579 3.25 4 3.25H20C20.4142 3.25 20.75 3.58579 20.75 4V20C20.75 20.4142 20.4142 20.75 20 20.75H4C3.58579 20.75 3.25 20.4142 3.25 20V4ZM11 7.75C11 7.19772 11.4477 6.75 12 6.75C12.5523 6.75 13 7.19772 13 7.75C13 8.30228 12.5523 8.75 12 8.75C11.4477 8.75 11 8.30228 11 7.75ZM9.75 10.75C9.75 10.3358 10.0858 10 10.5 10H12C12.4142 10 12.75 10.3358 12.75 10.75V15.5H13.5C13.9142 15.5 14.25 15.8358 14.25 16.25C14.25 16.6642 13.9142 17 13.5 17H12H10.5C10.0858 17 9.75 16.6642 9.75 16.25C9.75 15.8358 10.0858 15.5 10.5 15.5H11.25V11.5H10.5C10.0858 11.5 9.75 11.1642 9.75 10.75Z" fill="#262626"/>
</svg>

Before

Width:  |  Height:  |  Size: 750 B

After

Width:  |  Height:  |  Size: 764 B

+1 -1
View File
@@ -6,5 +6,5 @@ keywords:
- chain
- kobling
variant: Stroke
updated_at: 11.04.2023
updated_at: 04.05.2023
created_at: 07.03.2023
+1 -1
View File
@@ -20,5 +20,5 @@ keywords:
- ansvar
- paragraf
variant: Stroke
updated_at: 08.03.2023
updated_at: 03.05.2023
created_at: 07.03.2023
+1 -1
View File
@@ -5,5 +5,5 @@ keywords:
- "%"
- prosent
variant: Stroke
updated_at: 08.03.2023
updated_at: 05.05.2023
created_at: 07.03.2023
+1 -1
View File
@@ -6,5 +6,5 @@ keywords:
- legg til
- more
variant: Stroke
updated_at: 08.03.2023
updated_at: 03.05.2023
created_at: 07.03.2023
+1 -1
View File
@@ -1,3 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.25 9.5C10.25 8.92044 10.4399 8.49575 10.7178 8.21783C10.9957 7.93991 11.4204 7.75 12 7.75C12.5796 7.75 13.0043 7.93991 13.2822 8.21783C13.5601 8.49575 13.75 8.92044 13.75 9.5C13.75 9.65777 13.6859 9.84934 13.4991 10.1109C13.3076 10.379 13.0426 10.6467 12.7197 10.9697L12.6985 10.9909C12.4009 11.2884 12.0511 11.6381 11.7803 12.0172C11.4984 12.4118 11.25 12.9078 11.25 13.5V14C11.25 14.4142 11.5858 14.75 12 14.75C12.4142 14.75 12.75 14.4142 12.75 14V13.5C12.75 13.3422 12.8141 13.1507 13.0009 12.8891C13.1924 12.621 13.4574 12.3533 13.7803 12.0303L13.8015 12.0091C14.0991 11.7116 14.4489 11.3619 14.7197 10.9828C15.0016 10.5882 15.25 10.0922 15.25 9.5C15.25 8.57956 14.9399 7.75425 14.3428 7.15717C13.7457 6.56009 12.9204 6.25 12 6.25C11.0796 6.25 10.2543 6.56009 9.65717 7.15717C9.06009 7.75425 8.75 8.57956 8.75 9.5C8.75 9.91421 9.08579 10.25 9.5 10.25C9.91421 10.25 10.25 9.91421 10.25 9.5ZM12 15.5C11.4477 15.5 11 15.9477 11 16.5C11 17.0523 11.4477 17.5 12 17.5C12.5523 17.5 13 17.0523 13 16.5C13 15.9477 12.5523 15.5 12 15.5Z" fill="#262626"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.75 9C9.75 7.75736 10.7574 6.75 12 6.75H12.1716C13.3195 6.75 14.25 7.68054 14.25 8.82843C14.25 9.37966 14.031 9.90832 13.6412 10.2981L12.6412 11.2981C11.7504 12.1889 11.25 13.3971 11.25 14.6569C11.25 15.0711 11.5858 15.4069 12 15.4069C12.4142 15.4069 12.75 15.0711 12.75 14.6569C12.75 13.7949 13.0924 12.9682 13.7019 12.3588L14.7019 11.3588C15.373 10.6877 15.75 9.77748 15.75 8.82843C15.75 6.85212 14.1479 5.25 12.1716 5.25H12C9.92893 5.25 8.25 6.92893 8.25 9V9.5C8.25 9.91421 8.58579 10.25 9 10.25C9.41421 10.25 9.75 9.91421 9.75 9.5V9ZM12 16.5C11.4477 16.5 11 16.9477 11 17.5C11 18.0523 11.4477 18.5 12 18.5C12.5523 18.5 13 18.0523 13 17.5C13 16.9477 12.5523 16.5 12 16.5Z" fill="#262626"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 847 B

+1 -1
View File
@@ -13,5 +13,5 @@ keywords:
- veiledning
- spørsmålstegn
variant: Stroke
updated_at: 31.03.2023
updated_at: 04.05.2023
created_at: 07.03.2023
+1 -1
View File
@@ -6,5 +6,5 @@ keywords:
- crystal
- snø
variant: Stroke
updated_at: 08.03.2023
updated_at: 04.05.2023
created_at: 07.03.2023
+1 -1
View File
@@ -15,5 +15,5 @@ keywords:
- strand
- natur
variant: Stroke
updated_at: 08.03.2023
updated_at: 08.05.2023
created_at: 07.03.2023
+1 -1
View File
@@ -1,3 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.03033 5.96967C6.73744 5.67678 6.26256 5.67678 5.96967 5.96967C5.67678 6.26256 5.67678 6.73744 5.96967 7.03033L10.9393 12L5.96967 16.9697C5.67678 17.2626 5.67678 17.7374 5.96967 18.0303C6.26256 18.3232 6.73744 18.3232 7.03033 18.0303L12 13.0607L16.9697 18.0303C17.2626 18.3232 17.7374 18.3232 18.0303 18.0303C18.3232 17.7374 18.3232 17.2626 18.0303 16.9697L13.0607 12L18.0303 7.03033C18.3232 6.73744 18.3232 6.26256 18.0303 5.96967C17.7374 5.67678 17.2626 5.67678 16.9697 5.96967L12 10.9393L7.03033 5.96967Z" fill="#262626"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.53033 5.46967C6.23744 5.17678 5.76256 5.17678 5.46967 5.46967C5.17678 5.76256 5.17678 6.23744 5.46967 6.53033L10.9393 12L5.46967 17.4697C5.17678 17.7626 5.17678 18.2374 5.46967 18.5303C5.76256 18.8232 6.23744 18.8232 6.53033 18.5303L12 13.0607L17.4697 18.5303C17.7626 18.8232 18.2374 18.8232 18.5303 18.5303C18.8232 18.2374 18.8232 17.7626 18.5303 17.4697L13.0607 12L18.5303 6.53033C18.8232 6.23744 18.8232 5.76256 18.5303 5.46967C18.2374 5.17678 17.7626 5.17678 17.4697 5.46967L12 10.9393L6.53033 5.46967Z" fill="#262626"/>
</svg>

Before

Width:  |  Height:  |  Size: 680 B

After

Width:  |  Height:  |  Size: 680 B

+1 -1
View File
@@ -15,5 +15,5 @@ keywords:
- avvis
- avslå
variant: Stroke
updated_at: 13.04.2023
updated_at: 04.05.2023
created_at: 07.03.2023
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/aksel-icons",
"version": "2.9.3",
"version": "3.4.0",
"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",
+1
View File
@@ -0,0 +1 @@
/dist
+7
View File
@@ -0,0 +1,7 @@
# @navikt/aksel-stylelint
## 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
+173
View File
@@ -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
+58
View File
@@ -0,0 +1,58 @@
{
"name": "@navikt/aksel-stylelint",
"version": "3.4.0",
"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.0",
"@navikt/ds-tokens": "^3.4.0",
"@types/jest": "^29.0.0",
"concurrently": "7.2.1",
"copyfiles": "2.4.1",
"jest": "^29.0.0",
"jest-preset-stylelint": "^6.1.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",
},
];
+8
View File
@@ -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;
@@ -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,
};
+138
View File
@@ -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;
};
+18
View File
@@ -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/**"]
}
+137
View File
@@ -1,5 +1,142 @@
# @navikt/aksel
## 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
- Updated dependencies []:
- @navikt/ds-css@3.3.1
## 3.3.0
### Patch Changes
- Updated dependencies []:
- @navikt/ds-css@3.3.0
## 3.2.4
### Patch Changes
- Updated dependencies [[`30eee0dac`](https://github.com/navikt/aksel/commit/30eee0dac4e3e5a1379033283a6885e646e80458)]:
- @navikt/ds-css@3.2.4
## 3.2.3
### Patch Changes
- Updated dependencies [[`475e994f4`](https://github.com/navikt/aksel/commit/475e994f494b2080ffc05eb1684b6a244e3e2969), [`444e905e0`](https://github.com/navikt/aksel/commit/444e905e01965fd5cac40ff20c5225b072e67221)]:
- @navikt/ds-css@3.2.3
## 3.2.2
### Patch Changes
- Updated dependencies []:
- @navikt/ds-css@3.2.2
## 3.2.1
### Patch Changes
- Updated dependencies []:
- @navikt/ds-css@3.2.1
## 3.2.0
### Patch Changes
- Updated dependencies [[`affcab14c`](https://github.com/navikt/aksel/commit/affcab14c3d536929dfa64a36f5b43f9d0e8c3b7)]:
- @navikt/ds-css@3.2.0
## 3.1.3
### Patch Changes
- Updated dependencies [[`e8ecf309a`](https://github.com/navikt/aksel/commit/e8ecf309a910e47fd3cea6c54cd993ab1196910f)]:
- @navikt/ds-css@3.1.3
## 3.1.2
### Patch Changes
- Updated dependencies []:
- @navikt/ds-css@3.1.2
## 3.1.1
### Patch Changes
- Updated dependencies []:
- @navikt/ds-css@3.1.1
## 3.1.0
### Patch Changes
- Updated dependencies [[`9d2cd9e7f`](https://github.com/navikt/aksel/commit/9d2cd9e7fffb3cf6310c88229ee39ea85db19bca), [`f1c4c46eb`](https://github.com/navikt/aksel/commit/f1c4c46ebb0522561483f18e3b86b190cf9cc372)]:
- @navikt/ds-css@3.1.0
## 3.0.1
### Patch Changes
- Updated dependencies []:
- @navikt/ds-css@3.0.1
## 3.0.0
### Patch Changes
- Updated dependencies [[`166ee5feb`](https://github.com/navikt/aksel/commit/166ee5feb3c987c4e633eb449812116bfd865d3f), [`166ee5feb`](https://github.com/navikt/aksel/commit/166ee5feb3c987c4e633eb449812116bfd865d3f)]:
- @navikt/ds-css@3.0.0
## 2.9.8
### Patch Changes
- Updated dependencies []:
- @navikt/ds-css@2.9.8
## 2.9.7
### Patch Changes
- Updated dependencies []:
- @navikt/ds-css@2.9.7
## 2.9.6
### Patch Changes
- Updated dependencies []:
- @navikt/ds-css@2.9.6
## 2.9.5
### Patch Changes
- Updated dependencies []:
- @navikt/ds-css@2.9.5
## 2.9.4
### Patch Changes
- [#1952](https://github.com/navikt/aksel/pull/1952) [`27b2b4a11`](https://github.com/navikt/aksel/commit/27b2b4a11caf5ca05c96c686c453653d8a900e5f) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :truck: Flyttet Codemods from `@navikt/ds-codemods` -> `@navikt/aksel`.
- `@navikt/ds-codemods` vil bli deprecated ettehvert.
- Updated dependencies []:
- @navikt/ds-css@2.9.4
## 2.9.3
### Patch Changes
+190 -1
View File
@@ -1,6 +1,6 @@
# Aksel command line interface
CLI tool for managing CSS-imports and more when consuming Aksel-packages.
CLI tool for managing CSS-imports and Codemods when consuming Aksel-packages.
[Documentation](https://aksel.nav.no/preview/grunnleggende/kode/kommandolinje)
@@ -10,6 +10,195 @@ npx @navikt/aksel
commands:
css-imports: Generate css-imports for all components from Aksel
codemod: Codemods for version-migrations related to Aksel
```
## Codemods
Codemods are code-transformations that patches breaking changes in your project. This helps when migrating without spending time doing it manually.
```bash
To get started:
npx @navikt/aksel codemod --help
```
### v3
There is no general codemods for migrating from v2 -> v3.
#### CopyButton
`npx @navikt/aksel codemod v3-copybutton ...`
`<CopyToClipboard />` has been renamed to `<CopyButton />` and refactored.
- Namechange
- removed props `popoverText`, `iconPosition`, `popoverPlacement`
- changed variants
- refactored CSS and React-code. ⚠️ Overwritten CSS will not be migrated!
```diff
-import { CopyToClipboard } from "@navikt/ds-react-internal";
+import { CopyButton } from "@navikt/ds-react";
-<CopyToClipboard
+<CopyButton
- popoverText="popoverText"
- iconPosition="left"
- popoverPlacement="bottom-end"
copyText="Text to copy"
size="medium"
>
- text
+</CopyButton>
-</CopyToClipboard>
```
### v1 -> v2
[Documentation](https://aksel.nav.no/grunnleggende/kode/migrering#h76f47744d112)
v2-css: Patches changed css-variables
v2-js: Patches changed js-variables
v2-sass: Patches changed sass-variables
v2-less: Patches changed less-variables
#### css-tokens (--navds format)
`npx @navikt/aksel codemod v2-css src`
When having redefined a token, you will need to manually find and replace these instances after the codemod-run. A global search for `--v2-migration__` will show all found instances where you had redefined a token.
```diff
.example{
- color: var(--navds-global-color-gray-900);
+ color: var(--a-gray-900);
- --navds-semantic-color-text: red;
+ --v2-migration__navds-semantic-color-text: red;
}
```
#### sass/scss-tokens ($navds format)
`npx @navikt/aksel codemod v2-sass src`
```diff
.example{
- color: $navds-global-color-gray-900;
+ color: $a-gray-900;
}
```
#### less-tokens (@navds format)
`npx @navikt/aksel codemod v2-less src`
```diff
.example{
- color: @navds-global-color-gray-900;
+ color: @a-gray-900;
}
```
#### js-tokens
`npx @navikt/aksel codemod v2-js src`
```diff
- import { NavdsGlobalColorGray900 } from "@navikt/ds-tokens";
+ import { AGray900 } from "@navikt/ds-tokens";
const styled = styled.p`
- color: ${NavdsGlobalColorGray900};
+ color: ${AGray900};
`
```
### beta -> v1
[Documentation](https://aksel.nav.no/grunnleggende/kode/migrering#h50d54a5af8c1)
v1-preset: Runs all codemods for beta -> v1
v1-pagination: Fixes breaking API-changes for <Pagination /> component
v1-tabs: Fixes breaking API-changes for <Tabs /> component
v1-chat: Fixes breaking API-changes for <SpeechBubble /> (now <Chat/>) component
#### preset
Combines all avaliable codemods for migrating from beta -> v1. This transform should only be ran once.
Includes these transforms
- v1-tabs
- v1-chat
- v1-pagination
#### tabs
`npx @navikt/aksel codemod v1-tabs src`
```diff
<Tabs
defaultValue="logg"
onChange={(x) => console.log(x)}
- loop
+ iconPosition="left"
>
<Tabs.List
- loop
>
<Tabs.Tab
value="logg"
label="logg"
- iconPosition="left"
/>
</Tabs.List>
<Tabs.Panel value="logg">TabPanel for Logg-tab</Tabs.Panel>
</Tabs>
```
#### chat
`npx @navikt/aksel codemod v1-chat src`
```diff
-<SpeechBubble
+<Chat
- illustration={<Illustration />}
- topText="Ola Normann 01.01.21 14:00"
- illustrationBgColor="blue"
+ avatar={<Illustration />}
+ name="Ola Normann 01.01.21 14:00"
+ avatarBgColor="blue"
backgroundColor="red"
>
- <SpeechBubble.Bubble>
+ <Chat.Bubble>
Aute minim nisi sunt mollit duis sunt nulla minim non proident.
- </SpeechBubble.Bubble>
+ </Chat.Bubble>
-</SpeechBubble>
+</Chat>
```
#### pagination
`npx @navikt/aksel codemod v1-pagination src`
This codemod can only be ran once, since the size-scale will keep decreasing for each subsequent iteration.
```diff
-<Pagiation />
+<Pagiation size="small"/>
-<Pagiation size="medium"/>
+<Pagiation size="small"/>
-<Pagiation size="small"/>
+<Pagiation size="xsmall"/>
```
## License
+8
View File
@@ -0,0 +1,8 @@
const config = {
transform: { "^.+\\.js?$": "ts-jest", "^.+\\.ts?$": "ts-jest" },
testMatch: ["**/tests/*.test.ts"],
verbose: true,
rootDir: ".",
};
module.exports = config;
+19 -11
View File
@@ -1,23 +1,25 @@
{
"name": "@navikt/aksel",
"version": "2.9.3",
"description": "Aksel command line interface. Handles css-imports, codemods (planned) and more",
"version": "3.4.0",
"description": "Aksel command line interface. Handles css-imports, codemods and more",
"author": "Aksel | NAV designsystem team",
"license": "MIT",
"keywords": [
"react",
"command-line",
"Commandline",
"CLI",
"css",
"CDN"
"CDN",
"Codemods"
],
"files": [
"dist"
"dist",
"!dist/**/tests"
],
"scripts": {
"clean": "rimraf dist",
"build": "yarn clean && tsc -p tsconfig.json",
"dev": "tsc --watch -p tsconfig.json"
"dev": "tsc --watch -p tsconfig.json",
"test": "yarn build && jest",
"test:watch": "jest --watch"
},
"bin": "./dist/index.js",
"repository": {
@@ -25,22 +27,28 @@
"url": "git+https://github.com/navikt/aksel.git",
"directory": "@navikt/aksel"
},
"type": "module",
"homepage": "https://aksel.nav.no/grunnleggende/kode/kommandolinje",
"dependencies": {
"@navikt/ds-css": "2.9.3",
"@navikt/ds-css": "3.4.0",
"axios": "1.3.6",
"chalk": "4.1.0",
"clipboardy": "^3.0.0",
"clipboardy": "^2.3.0",
"commander": "10.0.1",
"enquirer": "^2.3.6",
"fast-glob": "3.2.11",
"figlet": "1.6.0",
"is-git-clean": "1.1.0",
"jscodeshift": "0.13.1",
"jscodeshift-add-imports": "1.0.10",
"lodash": "4.17.21",
"react-scanner": "^1.1.0"
},
"devDependencies": {
"@types/inquirer": "^9.0.3",
"@types/jest": "^29.0.0",
"jest": "^29.0.0",
"rimraf": "3.0.2",
"ts-jest": "^29.0.0",
"typescript": "^4.8.0"
},
"sideEffects": false,
+46
View File
@@ -0,0 +1,46 @@
import { Command } from "commander";
import figlet from "figlet";
import chalk from "chalk";
import { getMigrationString } from "./migrations.js";
import { validateGit, validateMigration } from "./validation.js";
import { runCodeshift } from "./run-codeshift.js";
const program = new Command();
export function codemodCommand() {
program.name(`${chalk.blueBright(`npx @navikt/aksel`)}`);
program
.command("codemod")
.addHelpText("beforeAll", figlet.textSync("Codemods"))
.addHelpText(
"afterAll",
chalk.gray(`\nAvailable migrations:\n${getMigrationString()}`)
)
.description("Migrations for Aksel components and more")
.argument("<migration>", "Migration name")
.option("-e, --ext [extension]", "default: js,ts,jsx,tsx,css,scss,less")
.option(
"-g, --glob [glob]",
"Globbing pattern, overrides --ext! Run with 'noglob' if using zsh-terminal. "
)
.option("-d, --dry-run", "Dry run, no changes will be made")
.option("-p, --print", "Print transformed files")
.option(
"-f, --force",
"Forcibly run migrations without checking git-changes"
)
.addHelpText(
"after",
`\nExample:
$ npx @navikt/aksel --dry-run v2-css`
)
.action((str, options) => {
validateMigration(str, program);
validateGit(options, program);
runCodeshift(str, options, program);
});
program.parse();
}
+98
View File
@@ -0,0 +1,98 @@
import chalk from "chalk";
export const migrations: {
[key: string]: {
description: string;
value: string;
path: string;
warning?: string;
}[];
} = {
"1.0.0": [
{
description: "Runs all codemods for beta -> v1 migration",
value: "v1-preset",
path: "v1.0.0/preset/preset",
},
{
description: "Fixes breaking API-changes for <Pagination /> component",
value: "v1-pagination",
path: "v1.0.0/pagination/pagination",
},
{
description: "Fixes breaking API-changes for <Tabs /> component",
value: "v1-tabs",
path: "v1.0.0/tabs/tabs",
},
{
description:
"Fixes breaking API-changes for <SpeechBubble /> (now <Chat/>) component",
value: "v1-chat",
path: "v1.0.0/chat/chat",
},
],
"2.0.0": [
{
description: "Patches changed css-variables",
value: "v2-css",
path: "v2.0.0/update-css-tokens/update-css-tokens",
},
{
description: "Patches changed js-variables",
value: "v2-js",
path: "v2.0.0/update-js-tokens/update-js-tokens",
},
{
description: "Patches changed sass-variables",
value: "v2-sass",
path: "v2.0.0/update-sass-tokens/update-sass-tokens",
},
{
description: "Patches changed less-variables",
value: "v2-less",
path: "v2.0.0/update-less-tokens/update-less-tokens",
},
],
"v3.0.0": [
{
description:
"Replaces deprecated <CopyToClipboard /> with <CopyButton />",
value: "v3-copybutton",
path: "v3.0.0/copybutton/copybutton",
warning:
"Remember to clean css-import from '@navikt/ds-css-internal' if no longer needed\nIf non-text was used as children, or different locales were handled, you need to manually fix this",
},
],
};
export function getMigrationPath(str: string) {
return Object.values(migrations)
.reduce((acc, val) => [...val, ...acc], [])
.find((x) => x.value === str)?.path;
}
export function getWarning(str: string) {
return Object.values(migrations)
.reduce((acc, val) => [...val, ...acc], [])
.find((x) => x.value === str)?.warning;
}
export function getMigrationNames() {
return Object.values(migrations).reduce(
(acc, val) => [...val.map((x) => x.value), ...acc],
[] as string[]
);
}
export function getMigrationString() {
let str = "";
Object.entries(migrations).forEach(([version, migrations]) => {
str += `\n${chalk.underline(version)}\n`;
migrations.forEach((migration) => {
str += `${chalk.blue(migration.value)}: ${migration.description}\n`;
});
});
return str;
}
@@ -0,0 +1,68 @@
import { Command } from "commander";
import fg from "fast-glob";
import * as jscodeshift from "jscodeshift/src/Runner";
import path from "path";
import { getMigrationPath, getWarning } from "./migrations";
import chalk from "chalk";
const ignoreNodeModules = [
"**/node_modules/**",
"**/dist/**",
"**/build/**",
"**/lib/**",
"**/.next/**",
];
export async function runCodeshift(
input: string,
options: any,
program: Command
) {
const codemodPath = path.join(
__dirname,
`./transforms/${getMigrationPath(input)}.js`
);
const filepaths = fg.sync([options.glob ?? getDefaultGlob(options?.ext)], {
cwd: process.cwd(),
ignore: ignoreNodeModules,
});
console.log("\nRunning migration:", chalk.green("input"));
options?.glob && console.log(`Using glob: ${chalk.green(options.glob)}\n`);
const warning = getWarning(input);
try {
await jscodeshift.run(codemodPath, filepaths, {
babel: true,
ignorePattern: ignoreNodeModules,
extensions: "tsx,ts,jsx,js",
parser: "tsx",
verbose: 2,
runInBand: true,
silent: false,
stdin: false,
dry: options?.dryRun,
force: options?.force,
print: options?.print,
});
warning && console.log(`\n${chalk.yellow(warning)}\n`);
} catch (error) {
program.error(chalk.red("Error:", error.message));
}
}
function getDefaultGlob(ext: string): string {
const defaultExt = "js,ts,jsx,tsx,css,scss,less";
return `**/*.{${cleanExtensions(ext ?? defaultExt).join(",")}}`;
}
function cleanExtensions(ext: string): string[] {
return ext
.split(",")
.map((e) => e.trim())
.map((e) => e.replace(".", ""));
}
@@ -0,0 +1,19 @@
import { getMigrationNames, getMigrationPath } from "../migrations";
import path from "path";
import fs from "fs";
describe("migrations", () => {
const values = getMigrationNames();
const paths = values.map((x) => getMigrationPath(x));
paths.forEach((x) => {
const checkPath = path.join(
process.cwd(),
"dist/codemod",
`transforms/${x}.js`
);
test(`Check transform-path: ${checkPath}`, () => {
expect(fs.existsSync(checkPath)).toBeTruthy();
});
});
});
+368
View File
@@ -0,0 +1,368 @@
/* prettier-ignore */
const tokens = [
["--navds-semantic-color-text-inverted", "--a-text-on-inverted"],
["--navds-semantic-color-text-muted", "--a-text-subtle"],
["--navds-semantic-color-text", "--a-text-default"],
["--navds-semantic-color-feedback-danger-text", "--a-text-danger"],
["--navds-semantic-color-link-visited", "--a-text-visited"],
["--navds-semantic-color-link", "--a-text-action"],
["--navds-spacing-32", "--a-spacing-32"],
["--navds-spacing-24", "--a-spacing-24"],
["--navds-spacing-20", "--a-spacing-20"],
["--navds-spacing-18", "--a-spacing-18"],
["--navds-spacing-16", "--a-spacing-16"],
["--navds-spacing-14", "--a-spacing-14"],
["--navds-spacing-12", "--a-spacing-12"],
["--navds-spacing-11", "--a-spacing-11"],
["--navds-spacing-10", "--a-spacing-10"],
["--navds-spacing-9", "--a-spacing-9"],
["--navds-spacing-8", "--a-spacing-8"],
["--navds-spacing-7", "--a-spacing-7"],
["--navds-spacing-6", "--a-spacing-6"],
["--navds-spacing-5", "--a-spacing-5"],
["--navds-spacing-4", "--a-spacing-4"],
["--navds-spacing-3", "--a-spacing-3"],
["--navds-spacing-2", "--a-spacing-2"],
["--navds-spacing-1", "--a-spacing-1"],
["--navds-global-color-purple-900", "--a-purple-900"],
["--navds-global-color-purple-800", "--a-purple-800"],
["--navds-global-color-purple-700", "--a-purple-700"],
["--navds-global-color-purple-600", "--a-purple-600"],
["--navds-global-color-purple-500", "--a-purple-500"],
["--navds-global-color-purple-400", "--a-purple-400"],
["--navds-global-color-purple-300", "--a-purple-300"],
["--navds-global-color-purple-200", "--a-purple-200"],
["--navds-global-color-purple-100", "--a-purple-100"],
["--navds-global-color-purple-50", "--a-purple-50"],
["--navds-global-color-orange-900", "--a-orange-900"],
["--navds-global-color-orange-800", "--a-orange-800"],
["--navds-global-color-orange-700", "--a-orange-700"],
["--navds-global-color-orange-600", "--a-orange-600"],
["--navds-global-color-orange-500", "--a-orange-500"],
["--navds-global-color-orange-400", "--a-orange-400"],
["--navds-global-color-orange-300", "--a-orange-300"],
["--navds-global-color-orange-200", "--a-orange-200"],
["--navds-global-color-orange-100", "--a-orange-100"],
["--navds-global-color-orange-50", "--a-orange-50"],
["--navds-global-color-limegreen-900", "--a-limegreen-900"],
["--navds-global-color-limegreen-800", "--a-limegreen-800"],
["--navds-global-color-limegreen-700", "--a-limegreen-700"],
["--navds-global-color-limegreen-600", "--a-limegreen-600"],
["--navds-global-color-limegreen-500", "--a-limegreen-500"],
["--navds-global-color-limegreen-400", "--a-limegreen-400"],
["--navds-global-color-limegreen-300", "--a-limegreen-300"],
["--navds-global-color-limegreen-200", "--a-limegreen-200"],
["--navds-global-color-limegreen-100", "--a-limegreen-100"],
["--navds-global-color-limegreen-50", "--a-limegreen-50"],
["--navds-global-color-lightblue-900", "--a-lightblue-900"],
["--navds-global-color-lightblue-800", "--a-lightblue-800"],
["--navds-global-color-lightblue-700", "--a-lightblue-700"],
["--navds-global-color-lightblue-600", "--a-lightblue-600"],
["--navds-global-color-lightblue-500", "--a-lightblue-500"],
["--navds-global-color-lightblue-400", "--a-lightblue-400"],
["--navds-global-color-lightblue-300", "--a-lightblue-300"],
["--navds-global-color-lightblue-200", "--a-lightblue-200"],
["--navds-global-color-lightblue-100", "--a-lightblue-100"],
["--navds-global-color-lightblue-50", "--a-lightblue-50"],
["--navds-global-color-green-900", "--a-green-900"],
["--navds-global-color-green-800", "--a-green-800"],
["--navds-global-color-green-700", "--a-green-700"],
["--navds-global-color-green-600", "--a-green-600"],
["--navds-global-color-green-500", "--a-green-500"],
["--navds-global-color-green-400", "--a-green-400"],
["--navds-global-color-green-300", "--a-green-300"],
["--navds-global-color-green-200", "--a-green-200"],
["--navds-global-color-green-100", "--a-green-100"],
["--navds-global-color-green-50", "--a-green-50"],
["--navds-global-color-deepblue-900", "--a-deepblue-900"],
["--navds-global-color-deepblue-800", "--a-deepblue-800"],
["--navds-global-color-deepblue-700", "--a-deepblue-700"],
["--navds-global-color-deepblue-600", "--a-deepblue-600"],
["--navds-global-color-deepblue-500", "--a-deepblue-500"],
["--navds-global-color-deepblue-400", "--a-deepblue-400"],
["--navds-global-color-deepblue-300", "--a-deepblue-300"],
["--navds-global-color-deepblue-200", "--a-deepblue-200"],
["--navds-global-color-deepblue-100", "--a-deepblue-100"],
["--navds-global-color-deepblue-50", "--a-deepblue-50"],
["--navds-global-color-red-900", "--a-red-900"],
["--navds-global-color-red-800", "--a-red-800"],
["--navds-global-color-red-700", "--a-red-700"],
["--navds-global-color-red-600", "--a-red-600"],
["--navds-global-color-red-500", "--a-red-500"],
["--navds-global-color-red-400", "--a-red-400"],
["--navds-global-color-red-300", "--a-red-300"],
["--navds-global-color-red-200", "--a-red-200"],
["--navds-global-color-red-100", "--a-red-100"],
["--navds-global-color-red-50", "--a-red-50"],
["--navds-global-color-blue-900", "--a-blue-900"],
["--navds-global-color-blue-800", "--a-blue-800"],
["--navds-global-color-blue-700", "--a-blue-700"],
["--navds-global-color-blue-600", "--a-blue-600"],
["--navds-global-color-blue-500", "--a-blue-500"],
["--navds-global-color-blue-400", "--a-blue-400"],
["--navds-global-color-blue-300", "--a-blue-300"],
["--navds-global-color-blue-200", "--a-blue-200"],
["--navds-global-color-blue-100", "--a-blue-100"],
["--navds-global-color-blue-50", "--a-blue-50"],
["--navds-global-color-gray-900", "--a-gray-900"],
["--navds-global-color-gray-800", "--a-gray-800"],
["--navds-global-color-gray-700", "--a-gray-700"],
["--navds-global-color-gray-600", "--a-gray-600"],
["--navds-global-color-gray-500", "--a-gray-500"],
["--navds-global-color-gray-400", "--a-gray-400"],
["--navds-global-color-gray-300", "--a-gray-300"],
["--navds-global-color-gray-200", "--a-gray-200"],
["--navds-global-color-gray-100", "--a-gray-100"],
["--navds-global-color-gray-50", "--a-gray-50"],
["--navds-global-color-nav-red", "--a-nav-red"],
["--navds-global-color-white", "--a-white"],
["--navds-global-color-transparent", "--a-transparent"],
["--navds-border-radius-full", "--a-border-radius-full"],
["--navds-border-radius-xlarge", "--a-border-radius-xlarge"],
["--navds-border-radius-large", "--a-border-radius-large"],
["--navds-border-radius-medium", "--a-border-radius-medium"],
["--navds-border-radius-small", "--a-border-radius-small"],
["--navds-z-index-tooltip", "--a-z-index-tooltip"],
["--navds-z-index-focus", "--a-z-index-focus"],
["--navds-z-index-popover", "--a-z-index-popover"],
["--navds-z-index-modal", "--a-z-index-modal"],
["--navds-font-weight-regular", "--a-font-weight-regular"],
["--navds-font-weight-bold", "--a-font-weight-bold"],
["--navds-font-size-small", "--a-font-size-small"],
["--navds-font-size-medium", "--a-font-size-medium"],
["--navds-font-size-large", "--a-font-size-large"],
["--navds-font-size-xlarge", "--a-font-size-xlarge"],
["--navds-font-size-heading-xsmall", "--a-font-size-heading-xsmall"],
["--navds-font-size-heading-small", "--a-font-size-heading-small"],
["--navds-font-size-heading-medium", "--a-font-size-heading-medium"],
["--navds-font-size-heading-large", "--a-font-size-heading-large"],
["--navds-font-size-heading-xlarge", "--a-font-size-heading-xlarge"],
["--navds-font-size-heading-2xlarge", "--a-font-size-heading-2xlarge"],
["--navds-font-line-height-medium", "--a-font-line-height-medium"],
["--navds-font-line-height-large", "--a-font-line-height-large"],
["--navds-font-line-height-xlarge", "--a-font-line-height-xlarge"],
["--navds-font-line-height-heading-xsmall","--a-font-line-height-heading-xsmall"],
["--navds-font-line-height-heading-small","--a-font-line-height-heading-small"],
["--navds-font-line-height-heading-medium","--a-font-line-height-heading-medium"],
["--navds-font-line-height-heading-large","--a-font-line-height-heading-large"],
["--navds-font-line-height-heading-xlarge","--a-font-line-height-heading-xlarge"],
["--navds-font-line-height-heading-2xlarge","--a-font-line-height-heading-2xlarge"],
["--navds-font-family", "--a-font-family"],
["--navds-semantic-color-feedback-info-icon", "--a-icon-info"],
["--navds-semantic-color-feedback-warning-icon", "--a-icon-warning"],
["--navds-semantic-color-feedback-danger-icon", "--a-icon-danger"],
["--navds-semantic-color-feedback-success-icon", "--a-icon-success"],
["--navds-semantic-color-feedback-info-background", "--a-surface-info-subtle"],
["--navds-semantic-color-feedback-warning-background", "--a-surface-warning-subtle"],
["--navds-semantic-color-interaction-danger-selected", "--a-surface-danger-active"],
["--navds-semantic-color-interaction-danger-hover", "--a-surface-danger-hover"],
["--navds-semantic-color-interaction-danger", "--a-surface-danger"],
["--navds-semantic-color-feedback-danger-background", "--a-surface-danger-subtle"],
["--navds-semantic-color-feedback-success-background", "--a-surface-success-subtle"],
["--navds-semantic-color-interaction-primary-hover-subtle","--a-surface-action-subtle-hover"],
["--navds-semantic-color-interaction-primary-selected","--a-surface-action-selected"],
["--navds-semantic-color-interaction-primary-hover","--a-surface-action-hover"],
["--navds-semantic-color-interaction-primary", "--a-surface-action"],
["--navds-semantic-color-canvas-background-inverted", "--a-surface-inverted"],
["--navds-semantic-color-component-background-inverted", "--a-surface-inverted"],
["--navds-semantic-color-component-background-alternate", "--a-surface-subtle"],
["--navds-semantic-color-component-background-light", "--a-surface-default"],
["--navds-semantic-color-canvas-background-light", "--a-bg-default"],
["--navds-semantic-color-canvas-background", "--a-bg-subtle"],
["--navds-semantic-color-border-inverted", "--a-border-on-inverted"],
["--navds-semantic-color-border-muted", "--a-border-default"],
["--navds-semantic-color-border", "--a-border-strong"],
["--navds-semantic-color-focus-inverted", "--a-border-focus-on-inverted"],
["--navds-semantic-color-focus", "--a-border-focus"],
["--navds-semantic-color-feedback-info-border", "--a-border-info"],
["--navds-semantic-color-feedback-warning-border", "--a-border-warning"],
["--navds-semantic-color-feedback-danger-border", "--a-border-danger"],
["--navds-semantic-color-feedback-success-border", "--a-border-success"],
["--navds-semantic-color-divider", "--a-border-divider"],
["--navds-shadow-focus-inverted", "--a-shadow-focus-inverted"],
["--navds-shadow-focus", "--a-shadow-focus"],
["--navds-shadow-xsmall", "--a-shadow-xsmall"],
["--navds-shadow-small", "--a-shadow-small"],
["--navds-shadow-medium", "--a-shadow-medium"],
["--navds-shadow-large", "--a-shadow-large"],
["--navds-shadow-xlarge", "--a-shadow-xlarge"],
/* Components */
["--navds-modal-color-overlay", "--a-surface-backdrop"],
["--navds-accordion-color-border", "--a-border-strong"],
["--navds-accordion-color-text-hover", "--a-surface-action"],
["--navds-accordion-color-border-hover", "--a-surface-action"],
["--navds-accordion-color-background-open", "--a-surface-action-subtle"],
["--navds-alert-color-error-border", "--a-border-danger"],
["--navds-alert-color-error-background", "--a-surface-danger-subtle"],
["--navds-alert-color-warning-border", "--a-border-warning"],
["--navds-alert-color-warning-background", "--a-surface-warning-subtle"],
["--navds-alert-color-info-border", "--a-border-info"],
["--navds-alert-color-info-background", "--a-surface-info-subtle"],
["--navds-alert-color-success-border", "--a-border-success"],
["--navds-alert-color-success-background", "--a-surface-success-subtle"],
["--navds-alert-color-border", "--a-border-default"],
["--navds-chat-color-avatar-background", "--a-bg-subtle"],
["--navds-chat-color-background", "--a-bg-subtle"],
["--navds-chat-color-avatar", "--a-text-default"],
["--navds-guide-panel-color-illustration-background", "--a-surface-action-subtle"],
["--navds-guide-panel-color-background", "--a-surface-default"],
["--navds-guide-panel-color-border", "--a-border-action"],
["--navds-error-summary-color-background", "--a-surface-default"],
["--navds-error-summary-color-border", "--a-border-danger"],
["--navds-confirmation-panel-color-background-checked", "--a-surface-success-subtle"],
["--navds-confirmation-panel-color-background-error", "--a-surface-danger-subtle"],
["--navds-confirmation-panel-color-border-checked", "--a-border-success"],
["--navds-confirmation-panel-color-border-error", "--a-border-danger"],
["--navds-confirmation-panel-color-background", "--a-surface-warning-subtle"],
["--navds-confirmation-panel-color-border", "--a-border-warning"],
["--navds-radio-checkbox-color-background-hover", "--a-surface-action-subtle"],
["--navds-radio-checkbox-color-background-checked", "--a-surface-action"],
["--navds-radio-checkbox-color-shadow-hover", "--a-surface-action"],
["--navds-radio-checkbox-color-shadow-checked", "--a-surface-action"],
["--navds-radio-checkbox-color-shadow-error", "--a-surface-danger"],
["--navds-radio-checkbox-color-label-hover", "--a-surface-action"],
["--navds-radio-checkbox-color-background", "--a-surface-default"],
["--navds-radio-checkbox-color-text", "--a-text-default"],
["--navds-radio-checkbox-color-shadow", "--a-border-strong"],
["--navds-select-color-border-hover", "--a-surface-action"],
["--navds-select-color-border-error", "--a-surface-danger"],
["--navds-select-color-shadow-error", "--a-surface-danger"],
["--navds-select-color-border-disabled","--a-gray-400"],
["--navds-select-color-background-disabled", "--a-surface-subtle"],
["--navds-switch-color-label-hover", "--a-surface-action"],
["--navds-select-color-background", "--a-surface-default"],
["--navds-select-color-border", "--a-border-strong"],
["--navds-switch-color-label", "--a-text-default"],
["--navds-switch-color-track-background-hover-checked", "--a-icon-success"],
["--navds-switch-color-track-shadow-inner-focus", "--a-surface-default"],
["--navds-switch-color-track-background-checked", "--a-border-success"],
["--navds-switch-color-track-background-hover", "--a-surface-neutral-hover"],
["--navds-switch-color-track-background", "--a-surface-neutral"],
["--navds-switch-color-thumb-icon-checked", "--a-border-success"],
["--navds-switch-color-thumb-loader-checked", "--a-border-success"],
["--navds-switch-color-thumb-icon", "--a-icon-subtle"],
["--navds-switch-color-thumb", "--a-surface-default"],
["--navds-textarea-color-counter-text-error", "--a-surface-danger"],
["--navds-textarea-color-border-hover", "--a-surface-action"],
["--navds-textarea-color-border-error", "--a-surface-danger"],
["--navds-textarea-color-shadow-error", "--a-surface-danger"],
["--navds-textarea-color-counter-text", "--a-text-subtle"],
["--navds-textarea-color-text-disabled", "--a-text-default"],
["--navds-textarea-color-border-disabled", "--a-gray-400"],
["--navds-textarea-color-background-disabled", "--a-surface-subtle"],
["--navds-textarea-color-background", "--a-surface-default"],
["--navds-textarea-color-border", "--a-border-strong"],
["--navds-help-text-color-popover-background", "--a-surface-info-subtle"],
["--navds-help-text-color-background-hover", "--a-surface-action"],
["--navds-help-text-color-background-focus", "--a-surface-action"],
["--navds-help-text-color-shadow-hover", "--a-surface-action"],
["--navds-help-text-color-hover", "--a-surface-default"],
["--navds-help-text-color-focus", "--a-surface-default"],
["--navds-help-text-color", "--a-surface-action"],
["--navds-link-color-text-focus", "--a-text-on-action"],
["--navds-link-color-text-active", "--a-text-on-action"],
["--navds-link-color-text", "--a-text-action"],
["--navds-link-color-icon", "--a-icon-action"],
["--navds-link-color-icon-focus", "--a-icon-on-action"],
["--navds-link-color-background-focus", "--a-border-focus"],
["--navds-link-color-background-active", "--a-border-focus"],
["--navds-link-color-on-info-background", "--a-text-default"],
["--navds-link-color-on-error-background", "--a-text-default"],
["--navds-loader-color-neutral-foreground", "--a-border-default"],
["--navds-loader-color-interaction-foreground", "--a-surface-action"],
["--navds-loader-color-inverted-foreground", "--a-surface-default"],
["--navds-loader-color-transparent-background", "--a-surface-transparent"],
["--navds-loader-color-foreground", "--a-border-default"],
["--navds-loader-color-background", "--a-surface-active"],
["--navds-modal-color-background", "--a-surface-default"],
["--navds-pagination-color-text-selected", "--a-text-on-action"],
["--navds-pagination-color-background-selected", "--a-surface-action-selected"],
["--navds-popover-color-background", "--a-surface-default"],
["--navds-popover-color-border", "--a-border-default"],
["--navds-tag-color-info-background", "--a-surface-info-subtle"],
["--navds-tag-color-info-border", "--a-border-info"],
["--navds-tag-color-warning-background", "--a-surface-warning-subtle"],
["--navds-tag-color-warning-border", "--a-border-warning"],
["--navds-tag-color-success-background", "--a-surface-success-subtle"],
["--navds-tag-color-success-border", "--a-border-success"],
["--navds-tag-color-error-background", "--a-surface-danger-subtle"],
["--navds-tag-color-error-border", "--a-border-danger"],
["--navds-tag-color-border", "--a-border-default"],
["--navds-tag-color-background", "--a-surface-subtle"],
["--navds-toggle-group-color-background-hover", "--a-surface-action-subtle"],
["--navds-toggle-group-color-text-hover", "--a-surface-action"],
["--navds-toggle-group-color-background-pressed", "--a-surface-action-selected"],
["--navds-toggle-group-color-text-pressed", "--a-text-on-action"],
["--navds-toggle-group-color-background", "--a-surface-default"],
["--navds-toggle-group-color-text", "--a-text-default"],
["--navds-toggle-group-color-border", "--a-border-divider"],
["--navds-panel-color-background", "--a-surface-default"],
["--navds-panel-color-border", "--a-border-default"],
["--navds-link-panel-color-border-hover", "--a-surface-action"],
["--navds-link-panel-color-title-hover", "--a-text-action"],
["--navds-link-panel-color-text", "--a-text-default"],
["--navds-table-row-color-background-selected-hover", "--a-surface-action-subtle-hover"],
["--navds-table-row-color-background-hover", "--a-bg-subtle"],
["--navds-table-row-color-background-selected", "--a-surface-action-subtle"],
["--navds-table-row-color-background-zebra", "--a-surface-subtle"],
["--navds-table-cell-color-border-hover", "--a-border-strong"],
["--navds-table-cell-color-border", "--a-border-default"],
["--navds-button-color-primary-background-hover", "--a-surface-action-hover"],
["--navds-button-color-primary-background-active", "--a-surface-action-active"],
["--navds-button-color-primary-border-focus", "--a-surface-default"],
["--navds-button-color-primary-text", "--a-text-on-action"],
["--navds-button-color-primary-background", "--a-surface-action"],
["--navds-button-color-secondary-border-focus-active-hover", "--a-surface-default"],
["--navds-button-color-secondary-text-hover", "--a-text-action"],
["--navds-button-color-secondary-text-active", "--a-text-on-action"],
["--navds-button-color-secondary-background-hover", "--a-surface-action-subtle-hover"],
["--navds-button-color-secondary-background-active", "--a-surface-action-active"],
["--navds-button-color-secondary-border", "--a-border-action"],
["--navds-button-color-secondary-text", "--a-text-action"],
["--navds-button-color-secondary-background", "--a-surface-default"],
["--navds-button-color-tertiary-background-hover", "--a-surface-action-subtle-hover"],
["--navds-button-color-tertiary-border-focus", "--a-border-action"],
["--navds-button-color-tertiary-border-active", "--a-surface-default"],
["--navds-button-color-tertiary-background-active", "--a-surface-action-active"],
["--navds-button-color-tertiary-text-active", "--a-text-on-action"],
["--navds-button-color-tertiary-text", "--a-text-action"],
["--navds-button-color-danger-background-hover", "--a-surface-danger-hover"],
["--navds-button-color-danger-background-active", "--a-surface-danger-active"],
["--navds-button-color-danger-border-focus", "--a-surface-default"],
["--navds-button-color-danger-background", "--a-surface-danger"],
["--navds-button-color-danger-text", "--a-text-on-danger"],
["--navds-error-message-color-text", "--a-text-danger"],
["--navds-search-color-border-hover", "--a-border-action"],
["--navds-search-color-clear-hover", "--a-text-action"],
["--navds-search-color-border-error", "--a-border-danger"],
["--navds-search-color-text", "--a-text-default"],
["--navds-search-color-border", "--a-border-default"],
["--navds-text-field-color-border-hover", "--a-border-action"],
["--navds-text-field-color-border-error", "--a-border-danger"],
["--navds-text-field-color-shadow-error", "--a-border-danger"],
["--navds-text-field-color-border-disabled", "--a-gray-400"],
["--navds-text-field-color-background-disabled", "--a-surface-subtle"],
["--navds-text-field-color-placeholder-text", "--a-text-subtle"],
["--navds-text-field-color-text-disabled", "--a-text-default"],
["--navds-text-field-color-text", "--a-text-default"],
["--navds-text-field-color-background", "--a-surface-default"],
["--navds-text-field-color-border", "--a-border-default"],
["--navds-dropdown-menu-color", "--a-text-default"],
["--navdsi-dropdown-item-color-text", "--a-text-action"],
["--navdsi-dropdown-item-color-background-hover", "--a-surface-action-subtle-hover"],
["--navdsi-dropdown-item-color-background-active", "--a-surface-action-active"],
["--navds-dropdown-item-color-focus", "--a-border-focus"],
["--navdsi-header-color-text", "--a-text-on-inverted"],
["--navdsi-header-color-background", "--a-surface-inverted"],
["--navdsi-header-color-border", "--a-gray-600"],
["--navdsi-header-color-hover", "--a-surface-inverted-hover"],
["--navdsi-header-color-active", "--a-surface-inverted-active"],
["--navds-button-icon-adjustment", "--ac-button-icon-margin"]
]
module.exports = { tokens };
@@ -0,0 +1,18 @@
import renameProps from "../../utils/rename-props";
/**
* @param {import('jscodeshift').FileInfo} file
* @param {import('jscodeshift').API} api
*/
export default function transformer(file, api, options) {
const j = api.jscodeshift;
const root = j(file.source);
const printOptions = options.printOptions;
return renameProps({
root,
componentName: options.component,
props: { [options.from]: options.to },
}).toSource(printOptions);
}
@@ -0,0 +1,17 @@
import { check } from "../../../utils/check";
const migration = "rename-prop";
const fixtures = ["rename"];
for (const fixture of fixtures) {
check(__dirname, {
fixture,
migration,
extension: "js",
options: {
component: "SpeechBubble",
from: "illustration",
to: "avatar",
},
});
}
@@ -0,0 +1,8 @@
/* eslint-disable react/jsx-no-undef */
export const Page = () => {
return (
<SpeechBubble illustration={<Illustration />}>
<div />
</SpeechBubble>
);
};
@@ -0,0 +1,8 @@
/* eslint-disable react/jsx-no-undef */
export const Page = () => {
return (
<SpeechBubble avatar={<Illustration />}>
<div />
</SpeechBubble>
);
};
@@ -0,0 +1,69 @@
import { getLineTerminator } from "../../../utils/lineterminator";
import renameProps from "../../../utils/rename-props";
/**
* @param {import('jscodeshift').FileInfo} file
* @param {import('jscodeshift').API} api
*/
export default function transformer(file, api, options) {
const j = api.jscodeshift;
let localName = "SpeechBubble";
const root = j(file.source);
/* Finds and replaces import from SpeechBubble -> Chat */
root
.find(j.ImportDeclaration)
.filter((path) => path.node.source.value === "@navikt/ds-react")
.forEach((imp) => {
imp.value.specifiers.forEach((x) => {
if (x.imported.name === "SpeechBubble") {
if (x.local.name !== x.imported.name) {
localName = x.local.name;
x.imported.name = "Chat";
} else {
x.imported.name = "Chat";
x.local.name = "Chat";
}
}
});
});
if (j(file.source).findJSXElements(localName)) {
renameProps({
root,
componentName: localName,
props: {
illustrationBgColor: "avatarBgColor",
illustration: "avatar",
topText: "name",
},
});
/* Find and replace name of all <SpeechBubble />*/
const compRoot = root.find(j.JSXElement, {
openingElement: { name: { name: localName } },
});
compRoot.forEach((x) => {
if (localName !== "SpeechBubble") return;
x.node.openingElement.name.name = "Chat";
x.node.closingElement.name.name = "Chat";
});
/* Need to handle dot-notations differently */
const child = root.find(j.JSXElement);
child.forEach((x) => {
if (
x.value.openingElement.name.type === "JSXMemberExpression" &&
x.value.openingElement.name.object.name === "SpeechBubble"
) {
x.value.openingElement.name.object.name = "Chat";
x.value.closingElement.name.object.name = "Chat";
}
});
}
return root.toSource(getLineTerminator(file.source));
}
Loaded 100 of 351 files, more files were not shown because too many files have changed in this diff. Show more