Compare commits

..
Author SHA1 Message Date
github-actions[bot] e3cf943ab3 Lerna versionbump [ci skip]
- @navikt/ds-css@0.11.3
2021-11-15 13:33:02 +00:00
Andreas Nordahl 59a3c71821 [FIX] Reduce body line-height to make struts smaller 2021-11-15 14:12:54 +01:00
Andreas NordahlandKen edab708a93 add security playbook card to front page. adjust styling (#1330)
Co-authored-by: Ken <ken.aleksander@gmail.com>
2021-11-12 15:50:05 +01:00
github-actions[bot] c291a6106f Lerna versionbump [ci skip]
- @navikt/ds-css@0.11.2
 - @navikt/ds-tokens@0.6.2
2021-11-12 13:43:24 +00:00
github-actions[bot]andKenAJoh 8f0601e93f [FIX] Tokens sync Figma (#1331)
Co-authored-by: KenAJoh <KenAJoh@users.noreply.github.com>
2021-11-12 14:27:21 +01:00
github-actions[bot] 03a9d1a554 Lerna versionbump [ci skip]
- @navikt/ds-css@0.11.1
 - @navikt/ds-icons@0.6.3
 - @navikt/ds-react@0.13.1
 - @navikt/ds-tokens@0.6.1
 - @navikt/ds-react-internal@0.8.1
2021-11-12 11:01:46 +00:00
github-actions[bot]andKenAJoh c58688a966 [FIX] Tokens sync Figma (#1328)
Co-authored-by: KenAJoh <KenAJoh@users.noreply.github.com>
2021-11-12 11:45:51 +01:00
Ken f242e5028c Fikset parsing til Style Dictionary format (#1329) 2021-11-12 11:08:51 +01:00
KenandAndreas Nordahl 92e13a173f [FIX ] ikon id prefikset (#1324)
Co-authored-by: Andreas Nordahl <andnorda@gmail.com>
2021-11-12 10:05:52 +01:00
github-actions[bot] a06b27a218 Lerna versionbump [ci skip]
- @navikt/ds-css@0.11.0
 - @navikt/ds-react@0.13.0
 - @navikt/ds-tokens@0.6.0
 - @navikt/ds-react-internal@0.8.0
2021-11-11 17:30:19 +00:00
KenandAndreas Nordahl 942f611c38 [FEATURE] Henter tokens fra Figma (#1270)
Co-authored-by: Andreas Nordahl <andnorda@gmail.com>
2021-11-11 18:08:31 +01:00
github-actions[bot] 9754e17057 Lerna versionbump [ci skip]
- @navikt/ds-react-internal@0.7.4
2021-11-11 16:13:22 +00:00
Ken 656d53c9e4 [FIX] Fjernet aria-haspopup fra toggle-button (#1325) 2021-11-11 16:57:21 +01:00
Ken d0bf3d81a8 Update update-icons.yml 2021-11-06 13:47:34 +01:00
github-actions[bot] 39c4c751d8 Lerna versionbump [ci skip]
- @navikt/ds-react@0.12.3
 - @navikt/ds-react-internal@0.7.3
2021-11-05 11:00:44 +00:00
Andreas Nordahl dacaf44ea8 [fix] controlled radio group no longer logs errors (#1322) 2021-11-05 11:42:35 +01:00
github-actions[bot] 8c4c73cc2e Lerna versionbump [ci skip]
- @navikt/ds-icons@0.6.2
 - @navikt/ds-react@0.12.2
 - @navikt/ds-react-internal@0.7.2
2021-11-03 10:23:10 +00:00
KenandKenAJoh 324eb29f02 [FIX] Ikonsynk Figma (#1319)
Co-authored-by: KenAJoh <KenAJoh@users.noreply.github.com>
2021-11-03 11:05:24 +01:00
github-actions[bot] ce0bde9ea3 Lerna versionbump [ci skip]
- @navikt/ds-icons@0.6.1
 - @navikt/ds-react@0.12.1
 - @navikt/ds-react-internal@0.7.1
2021-11-02 12:30:06 +00:00
KenandGitHub 4c26512709 [FIX] Ikonsynk fra Figma (Automatisk PR) (#1317)
Co-authored-by: GitHub <noreply@github.com>
2021-11-02 13:13:29 +01:00
Ken 17f5f9e379 github bot som Pr author 2021-11-02 11:39:39 +01:00
Ken 95eeb92a4e Update update-icons.yml 2021-11-02 11:10:10 +01:00
46 changed files with 4231 additions and 2189 deletions

No files matched your search

+9 -12
View File
@@ -1,8 +1,8 @@
name: Update Icons
on:
schedule:
- cron: 0 0 * * *
# schedule:
# - cron: 0 0 * * *
workflow_dispatch:
jobs:
@@ -10,8 +10,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0 # Required to retrieve git history
- uses: actions/setup-node@v1
with:
node-version: 14
@@ -27,19 +25,18 @@ jobs:
- name: postinstall
if: steps.node-cache.outputs.cache-hit == 'true'
run: yarn postinstall
- name: add Figma token to .env
run: echo "FIGMA_TOKEN=${{ secrets.FIGMA_IKONER_API }}" >> @navikt/core/icons/.env
- name: Update Icons
run: yarn update:icons
env:
FIGMA_TOKEN: ${{ secrets.FIGMA_IKONER_API }}
- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
with:
token: ${{ secrets.GIT_REPO }}
commit-message: "Oppdatert ikoner fra figma"
committer: GitHub <noreply@github.com>
commit-message: "Ikoner synket fra figma"
branch: figma-icons-sync
committer: GitHub <noreply@github.com>
author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>
signoff: false
delete-branch: true
title: "[FIX] Automatisk PR for ikoner"
labels: |
Icons
automated pr
title: "[FIX] Ikonsynk Figma"
+41
View File
@@ -0,0 +1,41 @@
name: Update tokens
on:
schedule:
- cron: 0 0 * * *
workflow_dispatch:
jobs:
update:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: 14
- name: Node-modules cache
uses: actions/cache@v2
id: node-cache
with:
path: "**/node_modules"
key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }}
- name: install
if: steps.node-cache.outputs.cache-hit != 'true'
run: yarn install
- name: postinstall
if: steps.node-cache.outputs.cache-hit == 'true'
run: yarn postinstall
- name: Update tokens
run: yarn update:tokens
env:
FIGMA_TOKEN: ${{ secrets.FIGMA_IKONER_API }}
- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
with:
token: ${{ secrets.GITHUB_TOKEN }}
branch: figma-tokens-sync
delete-branch: true
title: "[FEATURE] Tokens sync Figma"
commit-message: "Ikoner synket fra figma"
committer: GitHub <noreply@github.com>
signoff: false
+1 -1
View File
@@ -22,7 +22,7 @@ html {
body {
font-family: var(--navds-font-family);
line-height: 1.375;
line-height: 1.333;
color: var(--navds-color-text-primary);
font-size: 1.125rem;
}
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-css",
"version": "0.10.0",
"version": "0.11.3",
"private": false,
"description": "Css for NAV Designsystem components",
"author": "NAV Designsystem team",
@@ -21,7 +21,7 @@
"watch": "postcss --watch --use postcss-import -o dist/index.css index.css"
},
"devDependencies": {
"@navikt/ds-tokens": "^0.5.3",
"@navikt/ds-tokens": "^0.6.2",
"normalize.css": "^8.0.1",
"postcss": "^8.3.6",
"postcss-cli": "^8.3.1",
+3 -3
View File
@@ -1742,13 +1742,13 @@
{
"name": "SchoolBag",
"description": "",
"created_at": "2021-04-07T12:13:28.147Z",
"created_at": "2021-04-07T12:13:28.140Z",
"pageName": "Family"
},
{
"name": "SchoolBag",
"name": "SchoolBagFilled",
"description": "",
"created_at": "2021-04-07T12:13:28.140Z",
"created_at": "2021-04-07T12:13:28.147Z",
"pageName": "Family"
},
{
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-icons",
"version": "0.6.0",
"version": "0.6.3",
"private": false,
"description": "NAVs egne ikoner i SVG og React format",
"repository": {
@@ -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 3C12 4.65685 10.6569 6 9 6C7.34315 6 6 4.65685 6 3C6 1.34315 7.34315 0 9 0C10.6569 0 12 1.34315 12 3ZM23 14.5C23 15.3284 22.3284 16 21.5 16C20.6716 16 20 15.3284 20 14.5C20 13.6716 20.6716 13 21.5 13C22.3284 13 23 13.6716 23 14.5ZM4.68636 6C3.98108 6 3.36366 6.47353 3.18079 7.15469L0.000732422 19H1H3.25773V24H5.25773V19H7.25773V24H9.25773V19H11H12.0018L10.1893 11H13C13.5523 11 14 10.5523 14 10C14 9.44771 13.5523 9 13 9H9.5682C8.65406 7.19312 6.78502 6 4.68636 6ZM20 12C20 11.4477 19.5523 11 19 11C18.4477 11 18 11.4477 18 12V14H16.618L16.1708 13.1056C15.832 12.428 15.1395 12 14.382 12H14C13.4477 12 13 12.4477 13 13C13 13.5523 13.4477 14 14 14H14.382L14.8292 14.8944C15.168 15.572 15.8605 16 16.618 16H18C19.1046 16 20 15.1046 20 14V12ZM13 18C13 17.4477 13.4477 17 14 17H22C22.5523 17 23 17.4477 23 18C23 18.5523 22.5523 19 22 19H14C13.4477 19 13 18.5523 13 18Z" fill="#262626"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M13 3C13 4.65685 11.6569 6 10 6C8.34315 6 7 4.65685 7 3C7 1.34315 8.34315 0 10 0C11.6569 0 13 1.34315 13 3ZM24 14.5C24 15.3284 23.3284 16 22.5 16C21.6716 16 21 15.3284 21 14.5C21 13.6716 21.6716 13 22.5 13C23.3284 13 24 13.6716 24 14.5ZM5.68636 6C4.98108 6 4.36366 6.47353 4.18079 7.15469L1.00073 19H2H4.25773V24H6.25773V19H8.25773V24H10.2577V19H12H13.0018L11.1893 11H14C14.5523 11 15 10.5523 15 10C15 9.44771 14.5523 9 14 9H10.5682C9.65406 7.19312 7.78502 6 5.68636 6ZM21 12C21 11.4477 20.5523 11 20 11C19.4477 11 19 11.4477 19 12V14H17.618L17.1708 13.1056C16.832 12.428 16.1395 12 15.382 12H15C14.4477 12 14 12.4477 14 13C14 13.5523 14.4477 14 15 14H15.382L15.8292 14.8944C16.168 15.572 16.8605 16 17.618 16H19C20.1046 16 21 15.1046 21 14V12ZM14 18C14 17.4477 14.4477 17 15 17H23C23.5523 17 24 17.4477 24 18C24 18.5523 23.5523 19 23 19H15C14.4477 19 14 18.5523 14 18Z" fill="#262626"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

+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 2H14V3H13H11H10V2ZM8 3.58152V2C8 0.89543 8.89543 0 10 0H14C15.1046 0 16 0.895431 16 2V3.58152C18.9318 4.76829 21 7.64262 21 11V20C21 22.2091 19.2091 24 17 24H7C4.79086 24 3 22.2091 3 20V11C3 7.64262 5.06817 4.76829 8 3.58152ZM2 22V20V15V13C0.895431 13 0 13.8954 0 15V20C0 21.1046 0.895431 22 2 22ZM22 20V22C23.1046 22 24 21.1046 24 20V15C24 13.8954 23.1046 13 22 13V15V20ZM9 8C8.44772 8 8 8.44772 8 9C8 9.55228 8.44772 10 9 10H15C15.5523 10 16 9.55228 16 9C16 8.44772 15.5523 8 15 8H9ZM9 15H15V18H9V15ZM7 15C7 13.8954 7.89543 13 9 13H15C16.1046 13 17 13.8954 17 15V18C17 19.1046 16.1046 20 15 20H9C7.89543 20 7 19.1046 7 18V15Z" fill="#262626"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M10 2H14V3H13H11H10V2ZM8 3.58152V2C8 0.89543 8.89543 0 10 0H14C15.1046 0 16 0.895431 16 2V3.58152C18.9318 4.76829 21 7.64262 21 11V13H22C23.1046 13 24 13.8954 24 15V20C24 21.1046 23.1046 22 22 22H20.4649C19.7733 23.1956 18.4806 24 17 24H7C5.51944 24 4.22675 23.1956 3.53513 22H2C0.89543 22 0 21.1046 0 20V15C0 13.8954 0.895431 13 2 13H3V11C3 7.64262 5.06817 4.76829 8 3.58152ZM19 20V13V11C19 7.68629 16.3137 5 13 5H11C7.68629 5 5 7.68629 5 11V13V20C5 21.1046 5.89543 22 7 22H17C18.1046 22 19 21.1046 19 20ZM21 15V20H22V15H21ZM2 15H3V20H2L2 15ZM15 15H9V18H15V15ZM9 13C7.89543 13 7 13.8954 7 15V18C7 19.1046 7.89543 20 9 20H15C16.1046 20 17 19.1046 17 18V15C17 13.8954 16.1046 13 15 13H9ZM9 8C8.44772 8 8 8.44772 8 9C8 9.55228 8.44772 10 9 10H15C15.5523 10 16 9.55228 16 9C16 8.44772 15.5523 8 15 8H9Z" fill="#262626"/>
</svg>

Before

Width:  |  Height:  |  Size: 802 B

After

Width:  |  Height:  |  Size: 970 B

@@ -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="M10 2H14V3H13H11H10V2ZM8 3.58152V2C8 0.89543 8.89543 0 10 0H14C15.1046 0 16 0.895431 16 2V3.58152C18.9318 4.76829 21 7.64262 21 11V20C21 22.2091 19.2091 24 17 24H7C4.79086 24 3 22.2091 3 20V11C3 7.64262 5.06817 4.76829 8 3.58152ZM2 22V20V15V13C0.895431 13 0 13.8954 0 15V20C0 21.1046 0.895431 22 2 22ZM22 20V22C23.1046 22 24 21.1046 24 20V15C24 13.8954 23.1046 13 22 13V15V20ZM9 8C8.44772 8 8 8.44772 8 9C8 9.55228 8.44772 10 9 10H15C15.5523 10 16 9.55228 16 9C16 8.44772 15.5523 8 15 8H9ZM9 15H15V18H9V15ZM7 15C7 13.8954 7.89543 13 9 13H15C16.1046 13 17 13.8954 17 15V18C17 19.1046 16.1046 20 15 20H9C7.89543 20 7 19.1046 7 18V15Z" fill="#262626"/>
</svg>

After

Width:  |  Height:  |  Size: 802 B

+2 -1
View File
@@ -35,7 +35,8 @@ function defaultTemplate(
${imports}
${interfaces}
function ${componentName}(${props}) {
const titleId = _titleId ?? (title ? v4() : undefined);
const titleId = _titleId ?? (title ?
"icon-title-" + v4() : undefined);
return ${jsx};
}
${exports}`;
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-react",
"version": "0.12.0",
"version": "0.13.1",
"private": false,
"description": "NAV designsystem react components",
"author": "NAV Designsystem team",
@@ -35,7 +35,7 @@
},
"dependencies": {
"@material-ui/core": "^4.12.3",
"@navikt/ds-icons": "^0.6.0",
"@navikt/ds-icons": "^0.6.3",
"@popperjs/core": "^2.10.1",
"classnames": "^2.2.6",
"react-collapse": "^5.1.0",
@@ -29,10 +29,7 @@ test("checkbox group chains onChange calls", () => {
});
describe("Checkbox handles controlled-state correctly", () => {
const CheckboxComponent = ({
onChange = () => null,
value,
}) => (
const CheckboxComponent = ({ onChange = () => null, value }) => (
<CheckboxGroup legend="legend" onChange={onChange} value={value}>
<Checkbox value={"value1"}>label1</Checkbox>
<Checkbox value={"value2"}>label2</Checkbox>
@@ -55,7 +52,12 @@ describe("Checkbox handles controlled-state correctly", () => {
test("onChange called with expected values", () => {
const onGroupChange = jest.fn();
render(<CheckboxComponent onChange={onGroupChange} value={["value1", "value2"]} />);
render(
<CheckboxComponent
onChange={onGroupChange}
value={["value1", "value2"]}
/>
);
userEvent.click(screen.getByLabelText("label1"));
@@ -0,0 +1,63 @@
import React from "react";
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import faker from "faker";
import { Radio, RadioGroup } from ".";
const value1 = faker.datatype.string();
const label1 = faker.datatype.string();
const value2 = faker.datatype.string();
const label2 = faker.datatype.string();
const Group = (props) => (
<RadioGroup {...props} legend="legend">
<Radio value={value1}>{label1}</Radio>
<Radio value={value2}>{label2}</Radio>
</RadioGroup>
);
describe("Controlled RadioGroup", () => {
const originalError = console.error;
const mockError = jest.fn();
beforeEach(() => (console.error = mockError));
afterEach(() => (console.error = originalError));
test("doesnt console.error", () => {
const { rerender } = render(<Group value={value1} />);
rerender(<Group value={value2} />);
expect(mockError).toHaveBeenCalledTimes(0);
});
});
describe("Uncontrolled RadioGroup", () => {
test("handles state correctly", () => {
render(<Group />);
const input1 = screen.getByLabelText(label1) as HTMLInputElement;
const input2 = screen.getByLabelText(label2) as HTMLInputElement;
expect(input1.checked).toBe(false);
expect(input2.checked).toBe(false);
userEvent.click(screen.getByLabelText(label2));
expect(input1.checked).toBe(false);
expect(input2.checked).toBe(true);
});
test("handles defaultValue correctly", () => {
render(<Group defaultValue={value1} />);
const input1 = screen.getByLabelText(label1) as HTMLInputElement;
const input2 = screen.getByLabelText(label2) as HTMLInputElement;
expect(input1.checked).toBe(true);
expect(input2.checked).toBe(false);
userEvent.click(screen.getByLabelText(label2));
expect(input1.checked).toBe(false);
expect(input2.checked).toBe(true);
});
});
@@ -24,10 +24,14 @@ export const useRadio = (props: RadioProps) => {
inputProps: {
...inputProps,
name: radioGroup?.name,
defaultChecked:
radioGroup?.defaultValue === undefined
? undefined
: radioGroup?.defaultValue === props.value,
checked:
(radioGroup?.value ?? radioGroup?.defaultValue) === props.value
? true
: undefined,
radioGroup?.value === undefined
? undefined
: radioGroup?.value === props.value,
onChange: (e) => {
props.onChange && props.onChange(e);
radioGroup?.onChange && radioGroup.onChange(props.value);
+4 -1
View File
@@ -27,7 +27,10 @@
"files": [
{
"destination": "tokens.css",
"format": "css/variables"
"format": "css/variables",
"options": {
"outputReferences": true
}
}
]
},
+35
View File
@@ -0,0 +1,35 @@
import { writeFileSync } from "fs";
import { resolve } from "path";
import formatToStyleDictionary from "./format-sd";
import globalColorRefs, { ColorT } from "./global-color-ref";
import parseName from "./parse-name";
type FigmaColorsT = {
[key: string]: string;
};
const parseColors = async (figmaColors: FigmaColorsT) => {
/* Parse name and color into correct format */
const colors: ColorT[] = Object.entries(figmaColors)
.map(([key, value]) => ({
name: parseName(key),
color: value,
}))
.sort((a, b) => a.name.localeCompare(b.name))
.reverse();
/* Make semantic colors reference global colors */
const colorsWithRef = globalColorRefs(colors).reduce(
(old, color) => ({ [color.name]: color.color, ...old }),
{}
);
const styleDictionaryFormat = formatToStyleDictionary(colorsWithRef, "color");
writeFileSync(
resolve("./src/colors.json"),
JSON.stringify(styleDictionaryFormat, null, 2)
);
};
export default parseColors;
+23
View File
@@ -0,0 +1,23 @@
const deepen = (obj: { [key: string]: { value: string } }) => {
const result = {};
// For each object path (property key) in the object
for (const objectPath in obj) {
// Split path into component parts
const parts = objectPath.split("-");
// Create sub-objects along path as needed
let target = result;
while (parts.length > 1) {
const part = parts.shift();
target = target[part] = target[part] || {};
}
// Set value at end of path
target[parts[0]] = obj[objectPath];
}
return result;
};
export default deepen;
+46
View File
@@ -0,0 +1,46 @@
import Axios from "axios";
const { create } = Axios;
const dotenv = require("dotenv");
dotenv.config();
const FIGMA_FILE = "m0qpSPpsnNC9DwdmerGqJH";
const FigmaAxion = (token) =>
create({
headers: {
"X-FIGMA-TOKEN": token,
},
});
export const fetchFile = async () => {
const { data } = await FigmaAxion(process.env.FIGMA_TOKEN)
.get(`https://api.figma.com/v1/files/${FIGMA_FILE}`)
.catch((e) => {
throw e;
});
return data;
};
export const fetchFileStyles = async () => {
const {
data: {
meta: { styles },
},
} = await FigmaAxion(process.env.FIGMA_TOKEN)
.get(`https://api.figma.com/v1/files/${FIGMA_FILE}/styles`)
.catch((e) => {
throw e;
});
return styles;
};
export const fetchSyncDocument = async () => {
const {
data: { document },
} = await FigmaAxion(process.env.FIGMA_TOKEN)
.get(`https://api.figma.com/v1/files/A7fbghTh75Hk65SieEhaKK`)
.catch((e) => {
throw e;
});
return document;
};
+77
View File
@@ -0,0 +1,77 @@
import { Node, DOCUMENT } from "figma-api";
import paintToRgba from "./paint-to-rgba";
interface StyleId {
id: string;
styleType: "TEXT" | "FILL";
}
const styleFieldNames = {
TEXT: ["text"],
FILL: ["fill", "fills", "stroke", "strokes"],
};
const findNodeWithStyle = (node: Node<any>, styleId: StyleId): Node<any> => {
if (
node.hasOwnProperty("styles") &&
styleFieldNames[styleId.styleType]?.some(
(name) => node.styles[name] === styleId.id
)
) {
return node;
} else if (node.children) {
for (const child of node.children) {
const res = findNodeWithStyle(child, styleId);
if (res) {
return res;
}
}
}
};
const findStyleValue = (document: DOCUMENT, styleId: StyleId) => {
const node = findNodeWithStyle(document, styleId);
if (styleId.id === "5249:11258") {
}
switch (styleId.styleType) {
case "FILL":
if (node) {
if (
node.styles.stroke === styleId.id ||
node.styles.strokes === styleId.id
) {
return paintToRgba(node.strokes[0]);
} else {
return paintToRgba(node.fills[0]);
}
} else {
return undefined;
}
case "TEXT":
if (node) {
return node?.style;
} else {
return undefined;
}
}
};
const styleTypeName = {
FILL: "colors",
TEXT: "textStyles",
};
const getFileStyles = (file, fileStyles) =>
fileStyles.reduce(
(styles, { node_id: id, style_type: styleType, name }) => ({
...styles,
[styleTypeName[styleType]]: {
...styles[styleTypeName[styleType]],
[name]: findStyleValue(file.document, { id, styleType }),
},
}),
{}
);
export default getFileStyles;
+35
View File
@@ -0,0 +1,35 @@
import deepen from "./deepen";
const formatToStyleDictionary = (
colors: { [key: string]: string },
type: "color" | "spacing"
) => {
switch (type) {
case "color": {
return deepen(
Object.entries(colors).reduce(
(old, [key, val]) =>
val.startsWith("rgba")
? { ...old, [key]: { value: val } }
: {
...old,
[key]: { value: `{${val.replace(/-/g, ".")}.value}` },
},
{}
)
);
}
case "spacing": {
return deepen(
Object.entries(colors).reduce(
(old, [key, val]) => ({ ...old, [key]: { value: val } }),
{}
)
);
}
default:
return {};
}
};
export default formatToStyleDictionary;
@@ -0,0 +1,21 @@
import Color from "color";
export type ColorT = {
name: string;
color: string;
};
const globalColorRefs = (colors: ColorT[]) => {
const globalColors = colors.filter((c) => c.name.includes("-global-"));
return colors.map((c) => {
if (c.name.includes("-global-")) return c;
const globalColor = globalColors.find(
(g) => Color(g.color).string() === Color(c.color).string()
);
return globalColor ? { name: c.name, color: globalColor.name } : c;
});
};
export default globalColorRefs;
+28
View File
@@ -0,0 +1,28 @@
import dotenv from "dotenv";
import parseColors from "./colors";
import getFileStyles from "./file-styles";
import { fetchFile, fetchFileStyles, fetchSyncDocument } from "./fetch";
/* import Spacing from "./spacing"; */
dotenv.config();
const main = async () => {
await Promise.all([fetchFile(), fetchFileStyles(), fetchSyncDocument()])
.then(([file, styles, document]) => {
const parsedStyles = getFileStyles(file, styles);
parsedStyles.colors && parseColors(parsedStyles.colors);
// TODO: Get spacing by crawling like with colors
/* Spacing(document); */
})
.catch((e) => {
console.log("Failed fetching styles and file from figma");
throw e;
});
};
try {
main();
} catch (e) {
console.error(e.message);
}
@@ -0,0 +1,11 @@
import { Paint } from "figma-api";
const parseColor = ({ color, opacity }: Paint) => {
return `rgba(${Math.round(color.r * 255)}, ${Math.round(
color.g * 255
)}, ${Math.round(color.b * 255)}, ${
opacity !== undefined ? Math.round(opacity * 100) / 100 : 1
})`;
};
export default parseColor;
+6
View File
@@ -0,0 +1,6 @@
const parseName = (name: string) => {
const [scope, ...rest] = name.toLowerCase().split("/");
return `navds-${scope}-color-${rest.join("-")}`;
};
export default parseName;
+47
View File
@@ -0,0 +1,47 @@
import { CANVAS, DOCUMENT, FRAME, RECTANGLE } from "figma-api";
import formatToStyleDictionary from "./format-sd";
import { writeFileSync } from "fs";
import { resolve } from "path";
const Spacing = (document: DOCUMENT) => {
console.log("Updating spacing-tokens");
const spacingPage = document.children.find(
(c) => c.name === "Spacing"
) as CANVAS;
if (!spacingPage) {
throw new Error("Could not find spacing-page in document");
}
const spacingFrame = spacingPage.children.find(
(x) => x.name === "spacing"
) as FRAME;
if (!spacingFrame) {
throw new Error("Could not find spacing-frame in document");
}
const spaces = spacingFrame.children
.filter((x) => x.type === "RECTANGLE" && x.name.startsWith("spacing-"))
.reduce(
(old, space) => ({
...old,
[`navds-${space.name}`]: `${
(space as RECTANGLE).absoluteBoundingBox.width / 16
}rem`,
}),
{}
);
const styleDictionaryFormat = formatToStyleDictionary(spaces, "spacing");
writeFileSync(
resolve("./src/spacing.json"),
JSON.stringify(styleDictionaryFormat, null, 2)
);
console.log("Finished updating spacing-tokens\n");
};
export default Spacing;
@@ -0,0 +1,53 @@
import deepen from "../deepen";
describe("Check deepen parsing of key name", () => {
test("Convert spacing", () => {
expect(
deepen({
"navds-spacing-1": { value: "0.25rem" },
"navds-spacing-2": { value: "0.50rem" },
"navds-spacing-3": { value: "0.75rem" },
})
).toEqual({
navds: {
spacing: {
"1": { value: "0.25rem" },
"2": { value: "0.50rem" },
"3": { value: "0.75rem" },
},
},
});
});
test("Convert colors", () => {
expect(
deepen({
"navds-global-color-red-100": { value: "rbga(0,1,0,0)" },
"navds-global-color-green-100": { value: "rbga(0,4,0,0)" },
"navds-global-color-green-200": { value: "rbga(0,5,0,0)" },
"navds-semantic-color-border": { value: "rbga(0,10,0,0)" },
"navds-semantic-color-background": { value: "rbga(0,11,0,0)" },
})
).toEqual({
navds: {
global: {
color: {
red: {
"100": { value: "rbga(0,1,0,0)" },
},
green: {
"100": { value: "rbga(0,4,0,0)" },
"200": { value: "rbga(0,5,0,0)" },
},
},
},
semantic: {
color: {
border: { value: "rbga(0,10,0,0)" },
background: { value: "rbga(0,11,0,0)" },
},
},
},
});
});
});
@@ -0,0 +1,87 @@
[
{
"key": "018d5d2a8b92f9da2994e341b2e3b001a8822f3f",
"file_key": "0mfgBpI1SEf32yYXo5efgf",
"node_id": "1:5",
"style_type": "TEXT",
"thumbnail_url": "https://s3-alpha-sig.figma.com/checkpoints/vzj/ib4/z0B6PeiKmHxp5c6U/style_thumbnail_4.png?Expires=1636329600&Signature=UHMortZ3iu3smP3gjEZD9GdqIoADlILTQmP0AhrpcxwiN5S6GOBR9IcsWGqF6MvRxgZoqn5OctEM0GAC86QK2ed88j1u~bunEcbjK7-GPOiZJzxZ0~DkFOQpYyBQVqm~vTSXcOaWKHldJlrKXz4fUxeIeklygu~N7d1if5P1id9iikHrMODwiM6SMCjn09nwlXClVYAdzrt-F-o0J9fZ6nu9Vu7eKt-lKvisAQFbit7pqnUtZ9n0IEZLNFRIbWhIN~6hIvwCNhd0lquNFs4RAgWbMEwe7cOdMpzPUM~Vw4z1ChhUYkDrcDjkxuBfIpHyUj2FCQUqHomoCgHNpw97QQ__&Key-Pair-Id=APKAINTVSUGEWH5XD5UA",
"name": "test-text-style",
"description": "",
"created_at": "2021-10-26T17:18:57.283Z",
"updated_at": "2021-10-26T17:18:57.283Z",
"user": {
"id": "872810555172448100",
"handle": "Andreas Nordahl",
"img_url": "https://s3-alpha.figma.com/profile/544b7720-21c4-4170-b043-db1d569dfd87"
},
"sort_position": "!"
},
{
"key": "214a0ef007dee7ac3c1a8a0ec646ff157d730411",
"file_key": "0mfgBpI1SEf32yYXo5efgf",
"node_id": "1:3",
"style_type": "FILL",
"thumbnail_url": "https://s3-alpha-sig.figma.com/checkpoints/12q/5sp/wUcwiMEw4aN4noCs/style_thumbnail_3.png?Expires=1636329600&Signature=Z~1e2~wSQh2zWxf4pv1Z-vNsdYJVYa92vfuSwRlyOYlZGbtiSNN7MbyAFIrdcOicw1MJ-D8cJUT-nifAiD3BVQah9l~A3w~qHEhqgkKy5IP7-f34NX-MxnmxSGg4H5bWLvjGj4sa8SaqsWdugyteV0RejV0--qJCpRSoDdG0aMNa8hiehoxtJGSr8wCTCVENRb0fXAlYHtJDSbW9Ddok-LAUBdlXP0gO44MNKCuL~LQ9yz-MntiT5FGgq1bmA3e530l86cRnG9Ravgl~vgozJN7D4eF~msgH7l8T3S7SLXgy7ZpAmZ81eYYl2F2eqxlVHOAQu5s15f1L1kNjHmhfxg__&Key-Pair-Id=APKAINTVSUGEWH5XD5UA",
"name": "test-color-style",
"description": "",
"created_at": "2021-10-26T17:18:57.279Z",
"updated_at": "2021-10-26T17:18:57.279Z",
"user": {
"id": "872810555172448100",
"handle": "Andreas Nordahl",
"img_url": "https://s3-alpha.figma.com/profile/544b7720-21c4-4170-b043-db1d569dfd87"
},
"sort_position": "\""
},
{
"key": "b5548b234042939980688e7130cccc5e33f717e8",
"file_key": "0mfgBpI1SEf32yYXo5efgf",
"node_id": "2:6",
"style_type": "FILL",
"thumbnail_url": "https://s3-alpha-sig.figma.com/checkpoints/kyd/RB9/NkuKodQ2JxOFJAvH/style_thumbnail_2.png?Expires=1636329600&Signature=V1BXHDoHkAIBg-V1KpQzQhFPqO5nSVjJyZY7WOTigBynJ7jlf7QGxzJoefOEUHPKOVgtEs-9qXPABp9REBQ2kWXq21D08313VPkCBFDpXil1FHOW4bS1ogoFw4lZKQppHVNcNWnAxcm9Kt2NyiM1egR-SJX47r9W6v0ydIyvbOtvSds04nugHuEt-L3EC2NPx0TWAFlF-YO3Mqfn8PxikFwuFTQNPlrtiLxs~vcDtdfXiQvhs1McHFC6EhuTho0MJR25RPel1bwzhaOkqKB9IXvccjOx7d-BDcs8jty8cccbNimNO2CPJ5Bf4GuUqF2pDA5QHj9xr98aaVk-yepy8A__&Key-Pair-Id=APKAINTVSUGEWH5XD5UA",
"name": "red-see-through",
"description": "",
"created_at": "2021-10-26T17:18:57.276Z",
"updated_at": "2021-10-26T17:18:57.276Z",
"user": {
"id": "872810555172448100",
"handle": "Andreas Nordahl",
"img_url": "https://s3-alpha.figma.com/profile/544b7720-21c4-4170-b043-db1d569dfd87"
},
"sort_position": "#"
},
{
"key": "e2b9eb27b48ecfddb46430c578e26f9c3a4fe164",
"file_key": "0mfgBpI1SEf32yYXo5efgf",
"node_id": "3:12",
"style_type": "FILL",
"thumbnail_url": "https://s3-alpha-sig.figma.com/checkpoints/SCW/gWi/dNc5At7iWR4CmFxB/style_thumbnail_1.png?Expires=1636329600&Signature=RqsSEZMyvH-h6~X~xBL2Y4R0gnASnbXBHswjxGdqsx1YhBXkixKBO~--zG4TX-OT5cp4BXigXkHYvpd6AWazBuPdnAoN45MgZwv~qz8pgfRcRzUtJCtxnTzaKUQiLkR1Ln5AISUX7efr9KqVN4aDiagaZUXbVfyA7lnDVNbWPe6WN9f80DaIy5N6C4-lcpJWCWGCuLVkKAvI~ZI0L5qz6zJhpnQ~Rig0jn7gMidAQ92P6RvC4KTJREhCBYxPa4m1zsQg43wE4VGk75t-sWTs2On7j4k7754FRfmv1dHkGWuqk5MRaYaWOm8JzR1T2ln2pJYQzlz5wIhfPBtlMkptKA__&Key-Pair-Id=APKAINTVSUGEWH5XD5UA",
"name": "stroke-color-style",
"description": "",
"created_at": "2021-10-26T17:18:57.272Z",
"updated_at": "2021-10-26T17:18:57.272Z",
"user": {
"id": "872810555172448100",
"handle": "Andreas Nordahl",
"img_url": "https://s3-alpha.figma.com/profile/544b7720-21c4-4170-b043-db1d569dfd87"
},
"sort_position": "$"
},
{
"key": "13e8bd3685daaeb73693d308b56f35b98e99e643",
"file_key": "0mfgBpI1SEf32yYXo5efgf",
"node_id": "3:15",
"style_type": "FILL",
"thumbnail_url": "https://s3-alpha-sig.figma.com/checkpoints/dNp/kEC/VltRP5wczk9nIaJx/style_thumbnail_0.png?Expires=1636329600&Signature=c~j1TRW0Wvxn-ZZkNzk1NJQeymLJ3BJ5qvh~t8Cy8vwYLgxwVz0tz6LomPlwcNmx3xfv6TetosqudMzawSKbd3VBsRfACE84u4TNY7kTBsFkUkeI8JM~00g4LZJC9ESqB4VWIXcK1w0l6tAMdjHtJ8SRER9yF~t7N2sqebq4hOiuwTT1ZcpxpGhnAdRJGJfQt1kxbniryjWQfiadXLEIrHw25pEX0VbFJ2EAn9IL3Jhl2d49TBSE2MEZ5ht-1qU6m9Lnj1Hex3sU-EiS8DhDAeb~twtE7mGiPlXoXRSFUcpkB4EPS5wOa4D4wpq8G85MW3XlpNH08s6N5qG1x66-BQ__&Key-Pair-Id=APKAINTVSUGEWH5XD5UA",
"name": "stroke-color-style-2",
"description": "",
"created_at": "2021-10-26T17:18:57.267Z",
"updated_at": "2021-10-26T17:18:57.267Z",
"user": {
"id": "872810555172448100",
"handle": "Andreas Nordahl",
"img_url": "https://s3-alpha.figma.com/profile/544b7720-21c4-4170-b043-db1d569dfd87"
},
"sort_position": "%"
}
]
@@ -0,0 +1,30 @@
import file from "./file.json";
import fileStyles from "./file-styles.json";
import getFileStyles from "../file-styles";
test("get file styles", () => {
expect(getFileStyles(file, fileStyles)).toEqual({
colors: {
"test-color-style": "rgba(196, 196, 196, 1)",
"stroke-color-style": "rgba(84, 138, 83, 1)",
"stroke-color-style-2": "rgba(133, 111, 195, 0.69)",
"red-see-through": "rgba(219, 16, 16, 0.33)",
},
textStyles: {
"test-text-style": {
fontFamily: "Roboto",
fontPostScriptName: null,
fontWeight: 400,
textAutoResize: "WIDTH_AND_HEIGHT",
fontSize: 12,
textAlignHorizontal: "LEFT",
textAlignVertical: "TOP",
letterSpacing: 0,
lineHeightPx: 20,
lineHeightPercent: 142.22222900390625,
lineHeightPercentFontSize: 166.6666717529297,
lineHeightUnit: "PIXELS",
},
},
});
});
+472
View File
@@ -0,0 +1,472 @@
{
"document": {
"id": "0:0",
"name": "Document",
"type": "DOCUMENT",
"children": [
{
"id": "0:1",
"name": "Page 1",
"type": "CANVAS",
"children": [
{
"id": "1:2",
"name": "Rectangle 1",
"type": "RECTANGLE",
"blendMode": "PASS_THROUGH",
"absoluteBoundingBox": {
"x": -208,
"y": -113,
"width": 219,
"height": 119
},
"constraints": {
"vertical": "TOP",
"horizontal": "LEFT"
},
"fills": [
{
"blendMode": "NORMAL",
"type": "SOLID",
"color": {
"r": 0.7686274647712708,
"g": 0.7686274647712708,
"b": 0.7686274647712708,
"a": 1
}
}
],
"strokes": [],
"strokeWeight": 1,
"strokeAlign": "INSIDE",
"styles": {
"fills": "1:3"
},
"effects": []
},
{
"id": "1:4",
"name": "A Text",
"type": "TEXT",
"blendMode": "PASS_THROUGH",
"absoluteBoundingBox": {
"x": -224,
"y": 170,
"width": 34,
"height": 20
},
"constraints": {
"vertical": "TOP",
"horizontal": "LEFT"
},
"fills": [
{
"blendMode": "NORMAL",
"type": "SOLID",
"color": {
"r": 0,
"g": 0,
"b": 0,
"a": 1
}
}
],
"strokes": [],
"strokeWeight": 1,
"strokeAlign": "OUTSIDE",
"effects": [],
"characters": "A Text",
"style": {
"fontFamily": "Roboto",
"fontPostScriptName": null,
"fontWeight": 400,
"textAutoResize": "WIDTH_AND_HEIGHT",
"fontSize": 12,
"textAlignHorizontal": "LEFT",
"textAlignVertical": "TOP",
"letterSpacing": 0,
"lineHeightPx": 20,
"lineHeightPercent": 142.22222900390625,
"lineHeightPercentFontSize": 166.6666717529297,
"lineHeightUnit": "PIXELS"
},
"layoutVersion": 3,
"characterStyleOverrides": [],
"styleOverrideTable": {},
"styles": {
"text": "1:5"
}
},
{
"id": "3:14",
"name": "Frame 1",
"type": "FRAME",
"blendMode": "PASS_THROUGH",
"children": [
{
"id": "3:13",
"name": "Rectangle 2",
"type": "RECTANGLE",
"blendMode": "PASS_THROUGH",
"absoluteBoundingBox": {
"x": 58,
"y": 360,
"width": 257,
"height": 166
},
"constraints": {
"vertical": "TOP",
"horizontal": "LEFT"
},
"fills": [
{
"blendMode": "NORMAL",
"type": "SOLID",
"color": {
"r": 0.7686274647712708,
"g": 0.7686274647712708,
"b": 0.7686274647712708,
"a": 1
}
}
],
"strokes": [
{
"opacity": 0.6899999976158142,
"blendMode": "NORMAL",
"type": "SOLID",
"color": {
"r": 0.5208221077919006,
"g": 0.4344444274902344,
"b": 0.7666666507720947,
"a": 1
}
}
],
"strokeWeight": 1,
"strokeAlign": "INSIDE",
"styles": {
"stroke": "3:15"
},
"effects": []
}
],
"absoluteBoundingBox": {
"x": -149,
"y": 310,
"width": 502,
"height": 401
},
"constraints": {
"vertical": "TOP",
"horizontal": "LEFT"
},
"clipsContent": true,
"background": [
{
"blendMode": "NORMAL",
"type": "SOLID",
"color": {
"r": 1,
"g": 1,
"b": 1,
"a": 1
}
}
],
"fills": [
{
"blendMode": "NORMAL",
"type": "SOLID",
"color": {
"r": 1,
"g": 1,
"b": 1,
"a": 1
}
}
],
"strokes": [],
"strokeWeight": 1,
"strokeAlign": "INSIDE",
"backgroundColor": {
"r": 1,
"g": 1,
"b": 1,
"a": 1
},
"effects": []
}
],
"backgroundColor": {
"r": 0.8980392217636108,
"g": 0.8980392217636108,
"b": 0.8980392217636108,
"a": 1
},
"prototypeStartNodeID": null,
"flowStartingPoints": [],
"prototypeDevice": {
"type": "NONE",
"rotation": "NONE"
}
},
{
"id": "2:7",
"name": "Page 2",
"type": "CANVAS",
"children": [
{
"id": "2:8",
"name": "Frame 1",
"type": "FRAME",
"blendMode": "PASS_THROUGH",
"children": [
{
"id": "2:9",
"name": "Group 1",
"type": "GROUP",
"blendMode": "PASS_THROUGH",
"children": [
{
"id": "2:10",
"name": "Rectangle 2",
"type": "RECTANGLE",
"blendMode": "PASS_THROUGH",
"absoluteBoundingBox": {
"x": -137,
"y": -79,
"width": 219,
"height": 119
},
"constraints": {
"vertical": "TOP",
"horizontal": "LEFT"
},
"fills": [
{
"opacity": 0.33000001311302185,
"blendMode": "NORMAL",
"type": "SOLID",
"color": {
"r": 0.8583333492279053,
"g": 0.060798585414886475,
"b": 0.060798585414886475,
"a": 1
}
}
],
"strokes": [
{
"blendMode": "NORMAL",
"type": "SOLID",
"color": {
"r": 0.3293333053588867,
"g": 0.5416666865348816,
"b": 0.32499998807907104,
"a": 1
}
}
],
"strokeWeight": 1,
"strokeAlign": "INSIDE",
"styles": {
"fill": "2:6"
},
"effects": []
},
{
"id": "2:11",
"name": "A Text",
"type": "TEXT",
"blendMode": "PASS_THROUGH",
"absoluteBoundingBox": {
"x": -72,
"y": -26,
"width": 34,
"height": 20
},
"constraints": {
"vertical": "TOP",
"horizontal": "LEFT"
},
"fills": [
{
"blendMode": "NORMAL",
"type": "SOLID",
"color": {
"r": 0,
"g": 0,
"b": 0,
"a": 1
}
}
],
"strokes": [
{
"blendMode": "NORMAL",
"type": "SOLID",
"color": {
"r": 0.3293333053588867,
"g": 0.5416666865348816,
"b": 0.32499998807907104,
"a": 1
}
}
],
"strokeWeight": 1,
"strokeAlign": "OUTSIDE",
"styles": {
"strokes": "3:12",
"text": "1:5"
},
"effects": [],
"characters": "A Text",
"style": {
"fontFamily": "Roboto",
"fontPostScriptName": null,
"fontWeight": 400,
"textAutoResize": "WIDTH_AND_HEIGHT",
"fontSize": 12,
"textAlignHorizontal": "LEFT",
"textAlignVertical": "TOP",
"letterSpacing": 0,
"lineHeightPx": 20,
"lineHeightPercent": 142.22222900390625,
"lineHeightPercentFontSize": 166.6666717529297,
"lineHeightUnit": "PIXELS"
},
"layoutVersion": 3,
"characterStyleOverrides": [],
"styleOverrideTable": {}
}
],
"absoluteBoundingBox": {
"x": -137,
"y": -79,
"width": 219,
"height": 119
},
"constraints": {
"vertical": "TOP",
"horizontal": "LEFT"
},
"clipsContent": false,
"background": [],
"fills": [],
"strokes": [],
"strokeWeight": 1,
"strokeAlign": "INSIDE",
"backgroundColor": {
"r": 0,
"g": 0,
"b": 0,
"a": 0
},
"effects": []
}
],
"absoluteBoundingBox": {
"x": -228,
"y": -170,
"width": 455,
"height": 338
},
"constraints": {
"vertical": "TOP",
"horizontal": "LEFT"
},
"clipsContent": true,
"background": [
{
"blendMode": "NORMAL",
"type": "SOLID",
"color": {
"r": 1,
"g": 1,
"b": 1,
"a": 1
}
}
],
"fills": [
{
"blendMode": "NORMAL",
"type": "SOLID",
"color": {
"r": 1,
"g": 1,
"b": 1,
"a": 1
}
}
],
"strokes": [],
"strokeWeight": 1,
"strokeAlign": "INSIDE",
"backgroundColor": {
"r": 1,
"g": 1,
"b": 1,
"a": 1
},
"effects": []
}
],
"backgroundColor": {
"r": 0.8980392217636108,
"g": 0.8980392217636108,
"b": 0.8980392217636108,
"a": 1
},
"prototypeStartNodeID": null,
"flowStartingPoints": [],
"prototypeDevice": {
"type": "NONE",
"rotation": "NONE"
}
}
]
},
"components": {},
"componentSets": {},
"schemaVersion": 0,
"styles": {
"1:3": {
"key": "214a0ef007dee7ac3c1a8a0ec646ff157d730411",
"name": "test-color-style",
"styleType": "FILL",
"description": ""
},
"1:5": {
"key": "018d5d2a8b92f9da2994e341b2e3b001a8822f3f",
"name": "test-text-style",
"styleType": "TEXT",
"description": ""
},
"3:15": {
"key": "13e8bd3685daaeb73693d308b56f35b98e99e643",
"name": "stroke-color-style-2",
"styleType": "FILL",
"description": ""
},
"2:6": {
"key": "b5548b234042939980688e7130cccc5e33f717e8",
"name": "red-see-through",
"styleType": "FILL",
"description": ""
},
"3:12": {
"key": "e2b9eb27b48ecfddb46430c578e26f9c3a4fe164",
"name": "stroke-color-style",
"styleType": "FILL",
"description": ""
}
},
"name": "Untitled",
"lastModified": "2021-10-25T14:11:38Z",
"thumbnailUrl": "https://s3-alpha-sig.figma.com/thumbnails/0mfgBpI1SEf32yYXo5efgf/default?Expires=1636329600&Signature=UTYTy-IQUHP7nzFXJCQoB9ORcA3L0766gsczI2Il~zEcp1XMqZR6AkFCFJA0PSx-nmT3xkkS~wkEbWyK5--ncek6qZsGwA48GPcLf9NH4iViXg7noQFFrEauFYHihs2MJDuRo3YkLo6l5XTbtgJW2lKiP1yqNre91V9IMCyOsW1al-WaBALacZYYO2NOwV76URr8VCeUWhGwfTZcyj6bra40Arx-cw7gv2j3Zuz~c9CiRz42J9gNJpM2Xl2zPp6teEwvNUCMWvoiclcyTPm3g3mSXc5kQeSBTNNTpk46YEQP~XmHUXMu4d~s66d~3xXATV~QrWjAJ7lZQVYz7VBgSA__&Key-Pair-Id=APKAINTVSUGEWH5XD5UA",
"version": "1235987453",
"role": "owner",
"editorType": "figma"
}
@@ -0,0 +1,71 @@
import formatToStyledDictionary from "../format-sd";
describe("Check conversion to Styled-dictionary format", () => {
test("Converting colors", () => {
expect(
JSON.stringify(
formatToStyledDictionary(
{
"navds-global-color-red-500": "rgba(1,1,1,1)",
"navds-global-color-red-400": "rgba(1,2,1,1)",
"navds-global-color-red-300": "rgba(1,3,1,1)",
"navds-semantic-color-danger": "navds-global-color-red-400",
"navds-semantic-color-danger-hover": "navds-global-color-red-300",
},
"color"
)
)
).toBe(
JSON.stringify({
navds: {
global: {
color: {
red: {
"500": { value: "rgba(1,1,1,1)" },
"400": { value: "rgba(1,2,1,1)" },
"300": { value: "rgba(1,3,1,1)" },
},
},
},
semantic: {
color: {
danger: {
value: "{navds.global.color.red.400.value}",
hover: {
value: "{navds.global.color.red.300.value}",
},
},
},
},
},
})
);
});
test("Converting spacing", () => {
expect(
JSON.stringify(
formatToStyledDictionary(
{
"navds-spacing-1": "0.25rem",
"navds-spacing-2": "0.5rem",
"navds-spacing-3": "0.75rem",
"navds-spacing-4": "1rem",
},
"spacing"
)
)
).toBe(
JSON.stringify({
navds: {
spacing: {
"1": { value: "0.25rem" },
"2": { value: "0.5rem" },
"3": { value: "0.75rem" },
"4": { value: "1rem" },
},
},
})
);
});
});
@@ -0,0 +1,25 @@
import globalColorRefs from "../global-color-ref";
test("Global color refs", () => {
let colors = [
{ name: "navds-global-color-red-400", color: "#D05C4A" },
{ name: "navds-global-color-red-500", color: "#BA3A26" },
{ name: "navds-semantic-color-error", color: "#D05C4A" },
{ name: "navds-semantic-color-hover", color: "#BA3A26" },
{ name: "navds-semantic-color-noref", color: "#AAAAAA" },
];
let parsedColors = [
{ name: "navds-global-color-red-400", color: "#D05C4A" },
{ name: "navds-global-color-red-500", color: "#BA3A26" },
{ name: "navds-semantic-color-error", color: "navds-global-color-red-400" },
{ name: "navds-semantic-color-hover", color: "navds-global-color-red-500" },
{ name: "navds-semantic-color-noref", color: "#AAAAAA" },
];
const newColors = globalColorRefs(colors);
expect(JSON.stringify(newColors, null, 2)).toBe(
JSON.stringify(parsedColors, null, 2)
);
});
@@ -0,0 +1,62 @@
import { PaintType } from "figma-api";
import paintToRgba from "../paint-to-rgba";
describe("parse-color", () => {
test("white", () => {
expect(
paintToRgba({
type: PaintType.SOLID,
color: {
r: 1,
g: 1,
b: 1,
a: 1,
},
})
).toBe("rgba(255, 255, 255, 1)");
});
test("gray", () => {
expect(
paintToRgba({
type: PaintType.SOLID,
color: {
r: 0.9725490212440491,
g: 0.9725490212440491,
b: 0.9725490212440491,
a: 1,
},
})
).toBe("rgba(248, 248, 248, 1)");
});
test("transparent", () => {
expect(
paintToRgba({
type: PaintType.SOLID,
color: {
r: 1,
g: 1,
b: 1,
a: 1,
},
opacity: 0,
})
).toBe("rgba(255, 255, 255, 0)");
});
test("partly transparent", () => {
expect(
paintToRgba({
type: PaintType.SOLID,
color: {
r: 0.5208221077919006,
g: 0.4344444274902344,
b: 0.7666666507720947,
a: 1,
},
opacity: 0.6899999976158142,
})
).toBe("rgba(133, 111, 195, 0.69)");
});
});
@@ -0,0 +1,12 @@
import parseName from "../parse-name";
test("parse-name", () => {
new Map([
["Global/blue-500", "navds-global-color-blue-500"],
["Global/red-100", "navds-global-color-red-100"],
[
"Semantic/Interaction/primary-hover",
"navds-semantic-color-interaction-primary-hover",
],
]).forEach((value, key) => expect(parseName(key)).toBe(value));
});
+5
View File
@@ -0,0 +1,5 @@
module.exports = {
transform: {
"^.+\\.ts?$": "ts-jest",
},
};
+9 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-tokens",
"version": "0.5.3",
"version": "0.6.2",
"private": false,
"description": "Auto-generated design-tokens for NAV design-systems framework",
"author": "NAV Designsystem team",
@@ -20,7 +20,8 @@
"build": "node ./build.js",
"watch": "nodemon --watch src/index.js --exec \"yarn build\"",
"token": "style-dictionary build",
"test": "jest"
"test": "jest",
"update": "ts-node figma/index.ts dotenv/config"
},
"repository": {
"type": "git",
@@ -28,10 +29,15 @@
"directory": "@navikt/core/tokens"
},
"devDependencies": {
"@types/jest": "^27.0.1",
"color": "^4.0.1",
"dotenv": "^10.0.0",
"figma-api": "^1.7.0",
"jest": "^27.2.0",
"lodash": "^4.17.21",
"nodemon": "^2.0.12",
"style-dictionary": "^3.0.2"
"style-dictionary": "^3.0.2",
"ts-jest": "^27.0.5",
"ts-node": "^10.3.0"
}
}
+435
View File
@@ -0,0 +1,435 @@
{
"navds": {
"global": {
"color": {
"blue": {
"50": {
"value": "rgba(230, 240, 255, 1)"
},
"100": {
"value": "rgba(204, 225, 255, 1)"
},
"200": {
"value": "rgba(153, 195, 255, 1)"
},
"300": {
"value": "rgba(102, 165, 244, 1)"
},
"400": {
"value": "rgba(51, 134, 224, 1)"
},
"500": {
"value": "rgba(0, 103, 197, 1)"
},
"600": {
"value": "rgba(0, 86, 180, 1)"
},
"700": {
"value": "rgba(0, 69, 156, 1)"
},
"800": {
"value": "rgba(0, 52, 125, 1)"
},
"900": {
"value": "rgba(0, 34, 82, 1)"
}
},
"deepblue": {
"50": {
"value": "rgba(230, 241, 248, 1)"
},
"100": {
"value": "rgba(204, 226, 240, 1)"
},
"200": {
"value": "rgba(153, 196, 221, 1)"
},
"300": {
"value": "rgba(102, 163, 196, 1)"
},
"400": {
"value": "rgba(51, 128, 165, 1)"
},
"500": {
"value": "rgba(0, 91, 130, 1)"
},
"600": {
"value": "rgba(0, 80, 119, 1)"
},
"700": {
"value": "rgba(0, 67, 103, 1)"
},
"800": {
"value": "rgba(0, 52, 83, 1)"
},
"900": {
"value": "rgba(0, 36, 58, 1)"
}
},
"gray": {
"50": {
"value": "rgba(247, 247, 247, 1)"
},
"100": {
"value": "rgba(241, 241, 241, 1)"
},
"200": {
"value": "rgba(201, 201, 201, 1)"
},
"400": {
"value": "rgba(160, 160, 160, 1)"
},
"600": {
"value": "rgba(106, 106, 106, 1)"
},
"800": {
"value": "rgba(79, 79, 79, 1)"
},
"900": {
"value": "rgba(38, 38, 38, 1)"
}
},
"green": {
"50": {
"value": "rgba(243, 252, 245, 1)"
},
"100": {
"value": "rgba(204, 241, 214, 1)"
},
"200": {
"value": "rgba(153, 222, 173, 1)"
},
"300": {
"value": "rgba(102, 199, 134, 1)"
},
"400": {
"value": "rgba(51, 170, 95, 1)"
},
"500": {
"value": "rgba(6, 137, 58, 1)"
},
"600": {
"value": "rgba(0, 124, 46, 1)"
},
"700": {
"value": "rgba(0, 106, 35, 1)"
},
"800": {
"value": "rgba(0, 85, 25, 1)"
},
"900": {
"value": "rgba(0, 59, 15, 1)"
}
},
"lightblue": {
"50": {
"value": "rgba(235, 252, 255, 1)"
},
"100": {
"value": "rgba(216, 249, 255, 1)"
},
"200": {
"value": "rgba(181, 241, 255, 1)"
},
"300": {
"value": "rgba(151, 230, 255, 1)"
},
"400": {
"value": "rgba(124, 218, 248, 1)"
},
"500": {
"value": "rgba(102, 203, 236, 1)"
},
"600": {
"value": "rgba(76, 173, 205, 1)"
},
"700": {
"value": "rgba(54, 141, 168, 1)"
},
"800": {
"value": "rgba(35, 107, 125, 1)"
},
"900": {
"value": "rgba(19, 72, 82, 1)"
}
},
"limegreen": {
"50": {
"value": "rgba(253, 255, 230, 1)"
},
"100": {
"value": "rgba(249, 252, 204, 1)"
},
"200": {
"value": "rgba(236, 243, 153, 1)"
},
"300": {
"value": "rgba(217, 227, 102, 1)"
},
"400": {
"value": "rgba(193, 203, 51, 1)"
},
"500": {
"value": "rgba(162, 173, 0, 1)"
},
"600": {
"value": "rgba(147, 158, 0, 1)"
},
"700": {
"value": "rgba(127, 137, 0, 1)"
},
"800": {
"value": "rgba(102, 110, 0, 1)"
},
"900": {
"value": "rgba(71, 78, 0, 1)"
}
},
"nav": {
"red": {
"value": "rgba(195, 0, 0, 1)"
}
},
"orange": {
"50": {
"value": "rgba(255, 249, 240, 1)"
},
"100": {
"value": "rgba(255, 236, 204, 1)"
},
"200": {
"value": "rgba(255, 215, 153, 1)"
},
"300": {
"value": "rgba(255, 193, 102, 1)"
},
"400": {
"value": "rgba(255, 170, 51, 1)"
},
"500": {
"value": "rgba(255, 145, 0, 1)"
},
"600": {
"value": "rgba(212, 123, 0, 1)"
},
"700": {
"value": "rgba(168, 100, 0, 1)"
},
"800": {
"value": "rgba(125, 76, 0, 1)"
},
"900": {
"value": "rgba(82, 51, 0, 1)"
}
},
"purple": {
"50": {
"value": "rgba(239, 236, 244, 1)"
},
"100": {
"value": "rgba(224, 216, 233, 1)"
},
"200": {
"value": "rgba(192, 178, 210, 1)"
},
"300": {
"value": "rgba(161, 141, 187, 1)"
},
"400": {
"value": "rgba(130, 105, 162, 1)"
},
"500": {
"value": "rgba(99, 70, 137, 1)"
},
"600": {
"value": "rgba(82, 56, 116, 1)"
},
"700": {
"value": "rgba(65, 43, 93, 1)"
},
"800": {
"value": "rgba(48, 31, 70, 1)"
},
"900": {
"value": "rgba(31, 20, 47, 1)"
}
},
"red": {
"50": {
"value": "rgba(253, 232, 230, 1)"
},
"100": {
"value": "rgba(249, 210, 204, 1)"
},
"200": {
"value": "rgba(239, 168, 157, 1)"
},
"300": {
"value": "rgba(225, 128, 113, 1)"
},
"400": {
"value": "rgba(208, 92, 74, 1)"
},
"500": {
"value": "rgba(186, 58, 38, 1)"
},
"600": {
"value": "rgba(163, 42, 23, 1)"
},
"700": {
"value": "rgba(136, 29, 12, 1)"
},
"800": {
"value": "rgba(106, 18, 4, 1)"
},
"900": {
"value": "rgba(72, 9, 0, 1)"
}
},
"transparent": {
"value": "rgba(255, 255, 255, 0)"
},
"white": {
"value": "rgba(255, 255, 255, 1)"
}
}
},
"semantic": {
"color": {
"border": {
"default": {
"value": "{navds.global.color.gray.600.value}"
},
"muted": {
"value": "{navds.global.color.gray.400.value}"
}
},
"canvas": {
"background": {
"default": {
"value": "{navds.global.color.gray.100.value}"
},
"inverted": {
"value": "{navds.global.color.gray.900.value}"
},
"light": {
"value": "{navds.global.color.white.value}"
}
}
},
"component": {
"background": {
"alternate": {
"value": "{navds.global.color.gray.50.value}"
},
"inverted": {
"value": "{navds.global.color.gray.900.value}"
},
"light": {
"value": "{navds.global.color.white.value}"
}
}
},
"divider": {
"value": "{navds.global.color.gray.200.value}"
},
"feedback": {
"danger": {
"background": {
"value": "{navds.global.color.red.100.value}"
},
"border": {
"value": "{navds.global.color.red.500.value}"
},
"icon": {
"value": "{navds.global.color.red.500.value}"
},
"text": {
"value": "{navds.global.color.red.500.value}"
}
},
"info": {
"background": {
"value": "{navds.global.color.lightblue.100.value}"
},
"border": {
"value": "{navds.global.color.lightblue.700.value}"
},
"icon": {
"value": "{navds.global.color.lightblue.700.value}"
}
},
"success": {
"background": {
"value": "{navds.global.color.green.100.value}"
},
"border": {
"value": "{navds.global.color.green.500.value}"
},
"icon": {
"value": "{navds.global.color.green.600.value}"
}
},
"warning": {
"background": {
"value": "{navds.global.color.orange.100.value}"
},
"border": {
"value": "{navds.global.color.orange.600.value}"
},
"icon": {
"value": "{navds.global.color.orange.500.value}"
}
}
},
"focus": {
"value": "{navds.global.color.blue.800.value}",
"inverted": {
"value": "{navds.global.color.blue.200.value}"
}
},
"interaction": {
"danger": {
"default": {
"value": "{navds.global.color.red.500.value}"
},
"hover": {
"value": "{navds.global.color.red.600.value}"
},
"selected": {
"value": "{navds.global.color.red.700.value}"
}
},
"primary": {
"default": {
"value": "{navds.global.color.blue.500.value}"
},
"hover": {
"value": "{navds.global.color.blue.600.value}"
},
"selected": {
"value": "{navds.global.color.deepblue.500.value}"
}
}
},
"text": {
"default": {
"value": "{navds.global.color.gray.900.value}"
},
"inverted": {
"value": "{navds.global.color.white.value}"
},
"link": {
"value": "{navds.global.color.blue.500.value}",
"visited": {
"value": "{navds.global.color.purple.500.value}"
}
},
"muted": {
"value": "{navds.global.color.gray.600.value}"
}
}
}
}
}
}
+4 -9
View File
@@ -1,4 +1,6 @@
const Color = require("color");
const newColors = require("./colors.json");
const newSpacing = require("./spacing.json");
const baseFontSize = 16;
@@ -37,6 +39,8 @@ const gray = (n) => Color(lightgray).mix(Color(darkgray), n).hex();
module.exports = {
navds: {
...(newSpacing?.navds ?? {}),
...(newColors?.navds ?? {}),
color: {
white: { value: white },
darkgray: { value: darkgray },
@@ -213,15 +217,6 @@ module.exports = {
offset: { value: "0" },
},
},
spacing: Array(24)
.fill(0)
.reduce(
(spacing, _, index) => ({
...spacing,
[index + 1]: { value: `${(index + 1) / 4}rem` },
}),
{}
),
checkmark: {
image: {
white: {
+60
View File
@@ -0,0 +1,60 @@
{
"navds": {
"spacing": {
"1": {
"value": "0.25rem"
},
"2": {
"value": "0.5rem"
},
"3": {
"value": "0.75rem"
},
"4": {
"value": "1rem"
},
"5": {
"value": "1.25rem"
},
"6": {
"value": "1.5rem"
},
"7": {
"value": "1.75rem"
},
"8": {
"value": "2rem"
},
"9": {
"value": "2.25rem"
},
"10": {
"value": "2.5rem"
},
"11": {
"value": "2.75rem"
},
"12": {
"value": "3rem"
},
"14": {
"value": "3.5rem"
},
"16": {
"value": "4rem"
},
"18": {
"value": "4.5rem"
},
"20": {
"value": "5rem"
},
"24": {
"value": "6rem"
},
"32": {
"value": "8rem"
}
}
}
}
+6
View File
@@ -0,0 +1,6 @@
{
"compilerOptions": {
"esModuleInterop": true,
"resolveJsonModule": true
}
}
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-react-internal",
"version": "0.7.0",
"version": "0.8.1",
"private": false,
"description": "NAV internal designsystem react components",
"author": "NAV Designsystem team",
@@ -33,8 +33,8 @@
"watch": "tsc --watch -p tsconfig.esm.json"
},
"dependencies": {
"@navikt/ds-icons": "^0.6.0",
"@navikt/ds-react": "^0.12.0",
"@navikt/ds-icons": "^0.6.3",
"@navikt/ds-react": "^0.13.1",
"@popperjs/core": "^2.10.1",
"classnames": "^2.3.1",
"copy-to-clipboard": "^3.3.1",
@@ -35,7 +35,6 @@ const Toggle: ToggleType = forwardRef(
onClick && onClick(e);
}}
aria-expanded={isOpen}
aria-haspopup="menu"
className={cl("navdsi-dropdown__toggle", className)}
/>
);
+2 -1
View File
@@ -4,7 +4,7 @@
"version": "1.0.0",
"private": true,
"scripts": {
"test": "yarn workspace @navikt/ds-react test",
"test": "yarn workspace @navikt/ds-react test && yarn workspace @navikt/ds-tokens test",
"postinstall": "husky install",
"start": "yarn workspace website start",
"boot": "yarn clean:lib && yarn build:packages --stream",
@@ -18,6 +18,7 @@
"chromatic": "STORYBOOK_CHROMATIC=true npx chromatic --project-token x3xqdfgkujg",
"lerna:watch": "yarn run lerna run watch --stream",
"update:icons": "yarn workspace @navikt/ds-icons update",
"update:tokens": "yarn workspace @navikt/ds-tokens update",
"lint": "yarn lint:jsts && yarn lint:less && yarn lint:css",
"lint:jsts": "yarn eslint .",
"lint:less": "yarn stylelint --syntax less **/*.less",
+6 -18
View File
@@ -1,6 +1,6 @@
.card {
height: 22rem;
width: 18rem;
height: 24rem;
text-decoration: none;
color: var(--navds-color-darkgray);
display: flex;
@@ -25,11 +25,10 @@
}
.card__grid {
column-gap: 1rem;
row-gap: 1rem;
display: grid;
grid-template-columns: repeat(4, 1fr);
padding: 0;
display: flex;
gap: 1rem;
flex-wrap: wrap;
justify-content: center;
}
.card__icon {
@@ -63,6 +62,7 @@
font-size: 1.5rem;
line-height: 1.75rem;
font-weight: 600;
text-align: center;
}
.card:hover .card__title,
@@ -73,15 +73,3 @@
.card__content {
text-align: center;
}
@media screen and (max-width: 1350px) {
.card__grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media screen and (max-width: 700px) {
.card__grid {
grid-template-columns: repeat(1, 1fr);
}
}
@@ -1,7 +1,7 @@
import React from "react";
import { Ingress, Sidetittel } from "nav-frontend-typografi";
import Card from "../../card/Card";
import { Star, Facilitet, HandsHeart, Like } from "@navikt/ds-icons";
import { Star, Facilitet, HandsHeart, Like, Locked } from "@navikt/ds-icons";
import { NAVLogoDark } from "../../assets/images/svg";
import "./styles.less";
/* import Lenke from "nav-frontend-lenker"; */
@@ -61,6 +61,19 @@ const Forside = ({ ...props }) => (
icon={<Like focusable="false" />}
/>
</li>
<li>
<Card
content={
<>
<p>Hvordan vi utvikler sikker software i NAV.</p>
<p>(Krever GitHub bruker i navikt org)</p>
</>
}
title="Security Champions Playbook"
link="https://improved-train-2f244007.pages.github.io/"
icon={<Locked focusable="false" />}
/>
</li>
</ol>
</nav>
</div>
@@ -46,6 +46,7 @@
.card__grid {
list-style: none;
margin: 0;
padding: 0;
}
.card__wrapper {
+2398 -2120
View File
File diff suppressed because it is too large. Load diff