Compare commits

...
Author SHA1 Message Date
github-actions[bot]andgithub-actions[bot] 659e835da9 Version Packages (#2055)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-06-15 16:38:08 +02:00
Ken e10f4375b1 Merge branch 'main' of https://github.com/navikt/aksel 2023-06-15 16:34:25 +02:00
Ken 9a8bb26c36 🐛 Timeline brakk ved bruk av JSDOM-tester 2023-06-15 16:33:40 +02:00
github-actions[bot]andgithub-actions[bot] 69aea38784 Version Packages (#2053)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-06-15 15:55:48 +02:00
Ken 8f16d1571e 🎨 Oppdatert ikoner (#2054) 2023-06-15 15:51:47 +02:00
Marianne Røsvik e2265c9a78 Added two new icons (#2047) 2023-06-15 15:06:48 +02:00
Ken 925aa7a140 🐛 OverridableComponent omitter nå 'as' (#2051) 2023-06-15 14:46:34 +02:00
Ken 7c17e40cac 🐛 Datepicker og Monthpicker lukker nå popover ved escape (#2052) 2023-06-15 14:46:07 +02:00
github-actions[bot]andgithub-actions[bot] 3c8889ea88 Version Packages (#2050)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-06-13 16:49:54 +02:00
Ken e060961050 🐛 Fikset bruk av text-subtle på skjemaelementer (#2049) 2023-06-13 16:45:35 +02:00
Ken 18aa4ee7fb Merge branch 'main' of https://github.com/navikt/aksel 2023-06-09 14:36:38 +02:00
Ken f44edd76a2 Merge branch 'next' 2023-06-09 14:31:11 +02:00
github-actions[bot]andgithub-actions[bot] 1fa636bdd5 Version Packages (#2044)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-06-09 14:16:43 +02:00
Ken 44a75acb6b 🐛 className ble ikke riktig forwardet til period 2023-06-09 14:14:15 +02:00
Ken 550faee900 💄 Checkboard-pattern for transparent visning av tokens 2023-06-09 13:53:29 +02:00
Karl O 88b6174b0b 📝 La til next-logger så backend logging får rett log-level (#2042) 2023-06-09 13:34:31 +02:00
Ken fbf016b3bd ✨ Forbedringer for Aksel.nav.no UI (#2043) 2023-06-09 13:05:59 +02:00
09fa503b98 initial template for PR (#2019)
* initial template for PR

* update template

* update template

* 📝 Oppdatert template

---------

Co-authored-by: Ken <26967723+KenAJoh@users.noreply.github.com>
Co-authored-by: Ken <ken.aleksander@gmail.com>
2023-06-09 09:55:28 +02:00
Ken f5688485f5 ⬆️ Oppdatert Sanity 2023-06-08 18:43:14 +02:00
83 changed files with 2989 additions and 2222 deletions

No files matched your search

+17
View File
@@ -0,0 +1,17 @@
### :memo: PR Checklist
<!-- Remove non-relevant fields -->
- [ ] :sparkles: New component? Add CSS-mappings to `@navikt/core/css/config/_mappings.js`.
- [ ] :wastebasket: Are you deprecating a CSS class? (are you removing the last known reference to a CSS class?). Add it to `@navikt/aksel-stylelint/src/deprecations.ts` with a suitable description.
- [ ] :balance_scale: Is the feature/component/code sufficiently complex to warrant tests? Add some unit-tests :test_tube:
- [ ] :balance_scale: Does the feature/component add some complex user-interactions? Consider adding some [interaction-tests with storybook](https://storybook.js.org/docs/react/writing-tests/interaction-testing) :test_tube:
- [ ] :boom: Are there breaking changes? Consider adding a codemod for easier migration.
- [ ] :test_tube: Are all variations and cases shown in the storybook stories? Stories are used for [visual regression testing](https://www.chromatic.com/docs/), so make sure they are complete.
- [ ] Run `yarn changeset` for version and changelog generation
+15
View File
@@ -1,5 +1,20 @@
# @navikt/aksel-icons
## 4.1.6
## 4.1.5
### Patch Changes
- [#2054](https://github.com/navikt/aksel/pull/2054) [`8f16d1571`](https://github.com/navikt/aksel/commit/8f16d1571ec7cf452c09618a9a918ee2a634c75a) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :tada: Nye ikoner
- ChevronRightLast
- ChevronLeftLast
## 4.1.4
## 4.1.3
## 4.1.2
## 4.1.1
+1 -1
View File
@@ -15,5 +15,5 @@ keywords:
- Sammenføye
- Kildekontroll
variant: Stroke
updated_at: 08.03.2023
updated_at: 24.05.2023
created_at: 07.03.2023
@@ -5,5 +5,5 @@ keywords:
- left
- venstre
variant: Stroke
updated_at: 08.03.2023
updated_at: 14.06.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="M7.5 6.25C7.5 5.83579 7.16421 5.5 6.75 5.5C6.33579 5.5 6 5.83579 6 6.25V17.75C6 18.1642 6.33579 18.5 6.75 18.5C7.16421 18.5 7.5 18.1642 7.5 17.75V6.25ZM17.7803 7.03033C18.0732 6.73744 18.0732 6.26256 17.7803 5.96967C17.4874 5.67678 17.0126 5.67678 16.7197 5.96967L11.2197 11.4697C11.079 11.6103 11 11.8011 11 12C11 12.1989 11.079 12.3897 11.2197 12.5303L16.7197 18.0303C17.0126 18.3232 17.4874 18.3232 17.7803 18.0303C18.0732 17.7374 18.0732 17.2626 17.7803 16.9697L12.8107 12L17.7803 7.03033Z" fill="#262626"/>
</svg>

After

Width:  |  Height:  |  Size: 664 B

@@ -0,0 +1,12 @@
name: ChevronLeftFirst
category: Arrows
sub_category: Chevron
keywords:
- left
- venstre
- side
- first
- først
variant: Stroke
updated_at: 15.06.2023
created_at: 15.06.2023
@@ -6,5 +6,5 @@ keywords:
- høyre
- side
variant: Stroke
updated_at: 08.03.2023
updated_at: 09.06.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="M18 6.25C18 5.83579 17.6642 5.5 17.25 5.5C16.8358 5.5 16.5 5.83579 16.5 6.25V17.75C16.5 18.1642 16.8358 18.5 17.25 18.5C17.6642 18.5 18 18.1642 18 17.75V6.25ZM7.28033 6.21967C6.98744 5.92678 6.51256 5.92678 6.21967 6.21967C5.92678 6.51256 5.92678 6.98744 6.21967 7.28033L11.1893 12.25L6.21967 17.2197C5.92678 17.5126 5.92678 17.9874 6.21967 18.2803C6.51256 18.5732 6.98744 18.5732 7.28033 18.2803L12.7803 12.7803C13.0732 12.4874 13.0732 12.0126 12.7803 11.7197L7.28033 6.21967Z" fill="#262626"/>
</svg>

After

Width:  |  Height:  |  Size: 648 B

@@ -0,0 +1,10 @@
name: ChevronRightLast
category: Arrows
sub_category: Chevron
keywords:
- right
- høyre
- side
variant: Stroke
updated_at: 15.06.2023
created_at: 15.06.2023
+1 -1
View File
@@ -15,5 +15,5 @@ keywords:
- markup-språk
- kildekode
variant: Stroke
updated_at: 08.03.2023
updated_at: 24.05.2023
created_at: 07.03.2023
+1 -1
View File
@@ -13,5 +13,5 @@ keywords:
- dra og slippe
- skifte
variant: Stroke
updated_at: 08.03.2023
updated_at: 26.05.2023
created_at: 07.03.2023
+1 -1
View File
@@ -23,5 +23,5 @@ keywords:
- milepæler
- hendelser
variant: Stroke
updated_at: 08.03.2023
updated_at: 31.05.2023
created_at: 07.03.2023
+1 -1
View File
@@ -7,5 +7,5 @@ keywords:
- delete
- slett
variant: Stroke
updated_at: 08.03.2023
updated_at: 24.05.2023
created_at: 07.03.2023
+1 -1
View File
@@ -6,5 +6,5 @@ keywords:
- uploading
- send
variant: Stroke
updated_at: 08.03.2023
updated_at: 08.06.2023
created_at: 07.03.2023
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/aksel-icons",
"version": "4.1.2",
"version": "4.1.6",
"author": "Aksel | NAV",
"homepage": "https://aksel.nav.no/ikoner",
"repository": {
+8
View File
@@ -1,5 +1,13 @@
# @navikt/aksel-stylelint
## 4.1.6
## 4.1.5
## 4.1.4
## 4.1.3
## 4.1.2
## 4.1.1
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/aksel-stylelint",
"version": "4.1.2",
"version": "4.1.6",
"author": "Aksel | NAV",
"homepage": "https://aksel.nav.no/grunnleggende/kode/stylelint",
"repository": {
@@ -35,8 +35,8 @@
"dev": "yarn watch:lint"
},
"devDependencies": {
"@navikt/ds-css": "^4.1.2",
"@navikt/ds-tokens": "^4.1.2",
"@navikt/ds-css": "^4.1.6",
"@navikt/ds-tokens": "^4.1.6",
"@types/jest": "^29.0.0",
"concurrently": "7.2.1",
"copyfiles": "2.4.1",
+28
View File
@@ -1,5 +1,33 @@
# @navikt/aksel
## 4.1.6
### Patch Changes
- Updated dependencies []:
- @navikt/ds-css@4.1.6
## 4.1.5
### Patch Changes
- Updated dependencies []:
- @navikt/ds-css@4.1.5
## 4.1.4
### Patch Changes
- Updated dependencies [[`e06096105`](https://github.com/navikt/aksel/commit/e060961050c75ec815e5c125001f1ff99106e298)]:
- @navikt/ds-css@4.1.4
## 4.1.3
### Patch Changes
- Updated dependencies []:
- @navikt/ds-css@4.1.3
## 4.1.2
### Patch Changes
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/aksel",
"version": "4.1.2",
"version": "4.1.6",
"description": "Aksel command line interface. Handles css-imports, codemods and more",
"author": "Aksel | NAV designsystem team",
"license": "MIT",
@@ -29,7 +29,7 @@
},
"homepage": "https://aksel.nav.no/grunnleggende/kode/kommandolinje",
"dependencies": {
"@navikt/ds-css": "4.1.2",
"@navikt/ds-css": "4.1.6",
"axios": "1.3.6",
"chalk": "4.1.0",
"clipboardy": "^2.3.0",
+12
View File
@@ -1,5 +1,17 @@
# @navikt/ds-css
## 4.1.6
## 4.1.5
## 4.1.4
### Patch Changes
- [#2049](https://github.com/navikt/aksel/pull/2049) [`e06096105`](https://github.com/navikt/aksel/commit/e060961050c75ec815e5c125001f1ff99106e298) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :bug: Subtle-description på form-elementer brakk bruk av Readmore
## 4.1.3
## 4.1.2
## 4.1.1
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-css",
"version": "4.1.2",
"version": "4.1.6",
"description": "CSS for NAV Designsystem",
"author": "Aksel | NAV designsystem team",
"keywords": [
@@ -27,7 +27,7 @@
"css:get-version": "node config/get-version.js"
},
"devDependencies": {
"@navikt/ds-tokens": "^4.1.2",
"@navikt/ds-tokens": "^4.1.6",
"cssnano": "6.0.0",
"fast-glob": "3.2.11",
"lodash": "4.17.21",
+1
View File
@@ -41,6 +41,7 @@
border-left: 2px solid var(--ac-read-more-line, var(--a-border-divider));
margin-left: 13px;
padding-left: 13px;
color: var(--a-text-default);
}
.navds-read-more--small .navds-read-more__content {
+36
View File
@@ -1,5 +1,41 @@
# @navikt/ds-react
## 4.1.6
### Patch Changes
- [`9a8bb26c3`](https://github.com/navikt/aksel/commit/9a8bb26c36cfbb1a95cf28a043d2df3dbfe7185d) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :bug: Timeline-period brakk ved bruk av jsdom-tester
- Updated dependencies []:
- @navikt/aksel-icons@4.1.6
## 4.1.5
### Patch Changes
- [#2051](https://github.com/navikt/aksel/pull/2051) [`925aa7a14`](https://github.com/navikt/aksel/commit/925aa7a140bc0cd63e8884bea0bd478838c1aa17) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :bug: OverridableComponent fungerer nå med komponenter som allerede bruker 'as'-prop
- [#2052](https://github.com/navikt/aksel/pull/2052) [`7c17e40ca`](https://github.com/navikt/aksel/commit/7c17e40cac6703f00ce756276e9616deb73f6098) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :bug: floating-ui sendte ikke escape-events opp gjennom dom-treet
- Updated dependencies [[`8f16d1571`](https://github.com/navikt/aksel/commit/8f16d1571ec7cf452c09618a9a918ee2a634c75a)]:
- @navikt/aksel-icons@4.1.5
## 4.1.4
### Patch Changes
- Updated dependencies []:
- @navikt/aksel-icons@4.1.4
## 4.1.3
### Patch Changes
- [`44a75acb6`](https://github.com/navikt/aksel/commit/44a75acb6b904d614a01344f42111761a48cb7e2) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :bug: Classname ble ikke riktig forwardet til ikke-klikkbar Period i Timeline
- Updated dependencies []:
- @navikt/aksel-icons@4.1.3
## 4.1.2
### Patch Changes
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-react",
"version": "4.1.2",
"version": "4.1.6",
"description": "Aksel react-components for NAV designsystem",
"author": "Aksel | NAV designsystem team",
"license": "MIT",
@@ -38,7 +38,7 @@
},
"dependencies": {
"@floating-ui/react": "0.24.1",
"@navikt/aksel-icons": "^4.1.2",
"@navikt/aksel-icons": "^4.1.6",
"@radix-ui/react-tabs": "1.0.0",
"@radix-ui/react-toggle-group": "1.0.0",
"clsx": "^1.2.1",
@@ -114,6 +114,11 @@ export interface DatePickerDefaultProps
* @default "absolute"
*/
strategy?: "absolute" | "fixed";
/**
* Bubbles Escape keydown-event up trough DOM-tree. This is set to false by default to prevent closing components like Modal on Escape
* @default false
*/
bubbleEscape?: boolean;
}
export type DatePickerProps = DatePickerDefaultProps & ConditionalModeProps;
@@ -180,6 +185,7 @@ export const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(
onClose,
onOpenToggle,
strategy = "absolute",
bubbleEscape = false,
...rest
},
ref
@@ -251,6 +257,7 @@ export const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>(
role="dialog"
ref={ref}
strategy={strategy}
bubbleEscape={bubbleEscape}
>
<DayPicker
locale={getLocaleFromString(locale)}
@@ -319,6 +319,7 @@ export const useDatepicker = (
onOpenToggle: () => handleOpen(!open),
disabled,
disableWeekends,
bubbleEscape: true,
ref: setDaypickerRef,
};
@@ -312,6 +312,7 @@ export const useMonthpicker = (
open,
onOpenToggle: () => handleOpen(!open),
disabled,
bubbleEscape: true,
ref: setMonthpickerRef,
};
@@ -544,6 +544,7 @@ export const useRangeDatepicker = (
onOpenToggle: () => setOpen((x) => !x),
disabled,
disableWeekends,
bubbleEscape: true,
ref: setDaypickerRef,
};
@@ -86,6 +86,11 @@ export interface MonthPickerProps extends React.HTMLAttributes<HTMLDivElement> {
* @default "absolute"
*/
strategy?: "absolute" | "fixed";
/**
* Bubbles Escape keydown-event up trough DOM-tree. This is set to false by default to prevent closing components like Modal on Escape
* @default false
*/
bubbleEscape?: boolean;
}
interface MonthPickerComponent
@@ -153,6 +158,7 @@ export const MonthPicker = forwardRef<HTMLDivElement, MonthPickerProps>(
year,
onYearChange,
strategy = "absolute",
bubbleEscape = false,
},
ref
) => {
@@ -204,6 +210,7 @@ export const MonthPicker = forwardRef<HTMLDivElement, MonthPickerProps>(
id={ariaId}
className="navds-date"
strategy={strategy}
bubbleEscape={bubbleEscape}
>
<RootProvider
locale={getLocaleFromString(locale)}
+11 -1
View File
@@ -72,6 +72,11 @@ export interface PopoverProps extends HTMLAttributes<HTMLDivElement> {
* @default "absolute"
*/
strategy?: "absolute" | "fixed";
/**
* Bubbles Escape keydown-event up trough DOM-tree. This is set to false by default to prevent closing components like Modal on Escape
* @default false
*/
bubbleEscape?: boolean;
}
interface PopoverComponent
@@ -113,6 +118,7 @@ export const Popover = forwardRef<HTMLDivElement, PopoverProps>(
placement = "top",
offset,
strategy: userStrategy = "absolute",
bubbleEscape = false,
...rest
},
ref
@@ -143,7 +149,11 @@ export const Popover = forwardRef<HTMLDivElement, PopoverProps>(
const { getFloatingProps } = useInteractions([
useClick(context),
useDismiss(context),
useDismiss(context, {
bubbles: {
escapeKey: bubbleEscape,
},
}),
]);
useClientLayoutEffect(() => {
+5 -4
View File
@@ -88,14 +88,15 @@ export const Pin = forwardRef<HTMLButtonElement, TimelinePinProps>(
useCallback(
(e: FocusEvent) => {
if (
![refs.domReference.current, refs?.floating?.current].some(
(element) => element?.contains(e.target as Node)
)
![
refs.reference.current as HTMLButtonElement | null,
refs?.floating?.current,
].some((element) => element?.contains(e.target as Node))
) {
open && setOpen(false);
}
},
[open, refs.domReference, refs?.floating]
[open, refs.reference, refs?.floating]
)
);
@@ -90,14 +90,15 @@ const ClickablePeriod = React.memo(
useCallback(
(e: FocusEvent) => {
if (
![refs.domReference.current, refs?.floating?.current].some(
(element) => element?.contains(e.target as Node)
)
![
refs.reference.current as HTMLButtonElement | null,
refs?.floating?.current,
].some((element) => element?.contains(e.target as Node))
) {
open && setOpen(false);
}
},
[open, refs.domReference, refs?.floating]
[open, refs.reference, refs?.floating]
)
);
@@ -26,7 +26,7 @@ const NonClickablePeriod = ({
{...restProps}
className={cl(
getConditionalClasses(cropped, direction, status),
restProps?.classname
restProps?.className
)}
style={{
width: `${width}%`,
@@ -7,6 +7,6 @@ export interface OverridableComponent<Component, Element extends HTMLElement> {
props: {
as: As;
} & Component &
Omit<React.ComponentPropsWithRef<As>, keyof Component>
Omit<React.ComponentPropsWithRef<As>, keyof Component | "as">
): ReturnType<React.FC>;
}
+8
View File
@@ -1,5 +1,13 @@
# @navikt/ds-tailwind
## 4.1.6
## 4.1.5
## 4.1.4
## 4.1.3
## 4.1.2
## 4.1.1
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-tailwind",
"version": "4.1.2",
"version": "4.1.6",
"description": "Tailwind config based on @navikt/ds-tokens",
"author": "Aksel | NAV designsystem team",
"keywords": [
@@ -22,7 +22,7 @@
"directory": "@navikt/core/tailwind"
},
"devDependencies": {
"@navikt/ds-tokens": "^4.1.2",
"@navikt/ds-tokens": "^4.1.6",
"@types/jest": "^29.0.0",
"color": "4.2.3",
"jest": "^29.0.0",
+8
View File
@@ -1,5 +1,13 @@
# @navikt/ds-tokens
## 4.1.6
## 4.1.5
## 4.1.4
## 4.1.3
## 4.1.2
## 4.1.1
+66 -37
View File
@@ -47,27 +47,27 @@
"name": "--a-font-family",
"value": "\"Source Sans Pro\", Arial, sans-serif"
},
{ "name": "--a-font-weight-bold", "value": "600" },
{ "name": "--a-font-weight-regular", "value": "400" },
{ "name": "--a-font-line-height-heading-2xlarge", "value": "3.25rem" },
{ "name": "--a-font-line-height-heading-xlarge", "value": "2.5rem" },
{ "name": "--a-font-line-height-heading-large", "value": "2.25rem" },
{ "name": "--a-font-line-height-heading-medium", "value": "2rem" },
{ "name": "--a-font-line-height-heading-small", "value": "1.75rem" },
{ "name": "--a-font-line-height-heading-xsmall", "value": "1.5rem" },
{ "name": "--a-font-line-height-xlarge", "value": "1.75rem" },
{ "name": "--a-font-line-height-large", "value": "1.5rem" },
{ "name": "--a-font-line-height-medium", "value": "1.25rem" },
{ "name": "--a-font-size-heading-2xlarge", "value": "2.5rem" },
{ "name": "--a-font-size-heading-xlarge", "value": "2rem" },
{ "name": "--a-font-size-heading-large", "value": "1.75rem" },
{ "name": "--a-font-size-heading-medium", "value": "1.5rem" },
{ "name": "--a-font-size-heading-small", "value": "1.25rem" },
{ "name": "--a-font-size-heading-xsmall", "value": "1.125rem" },
{ "name": "--a-font-size-xlarge", "value": "1.25rem" },
{ "name": "--a-font-size-large", "value": "1.125rem" },
{ "name": "--a-font-weight-bold", "value": "600" },
{ "name": "--a-font-size-small", "value": "0.875rem" },
{ "name": "--a-font-size-medium", "value": "1rem" },
{ "name": "--a-font-size-small", "value": "0.875rem" }
{ "name": "--a-font-size-large", "value": "1.125rem" },
{ "name": "--a-font-size-xlarge", "value": "1.25rem" },
{ "name": "--a-font-size-heading-xsmall", "value": "1.125rem" },
{ "name": "--a-font-size-heading-small", "value": "1.25rem" },
{ "name": "--a-font-size-heading-medium", "value": "1.5rem" },
{ "name": "--a-font-size-heading-large", "value": "1.75rem" },
{ "name": "--a-font-size-heading-xlarge", "value": "2rem" },
{ "name": "--a-font-size-heading-2xlarge", "value": "2.5rem" },
{ "name": "--a-font-line-height-medium", "value": "1.25rem" },
{ "name": "--a-font-line-height-large", "value": "1.5rem" },
{ "name": "--a-font-line-height-xlarge", "value": "1.75rem" },
{ "name": "--a-font-line-height-heading-xsmall", "value": "1.5rem" },
{ "name": "--a-font-line-height-heading-small", "value": "1.75rem" },
{ "name": "--a-font-line-height-heading-medium", "value": "2rem" },
{ "name": "--a-font-line-height-heading-large", "value": "2.25rem" },
{ "name": "--a-font-line-height-heading-xlarge", "value": "2.5rem" },
{ "name": "--a-font-line-height-heading-2xlarge", "value": "3.25rem" }
],
"global-base": [
{ "name": "--a-transparent", "value": "rgba(255, 255, 255, 0)" },
@@ -195,26 +195,34 @@
{ "name": "--a-purple-900", "value": "rgba(31, 20, 47, 1)" }
],
"semantic-border": [
"semantic-border-default": [
{ "name": "--a-border-default", "value": "rgba(0, 0, 0, 0.44)" },
{ "name": "--a-border-strong", "value": "rgba(0, 0, 0, 0.65)" },
{ "name": "--a-border-divider", "value": "rgba(0, 0, 0, 0.19)" },
{ "name": "--a-border-subtle", "value": "rgba(0, 0, 0, 0.1)" },
{ "name": "--a-border-subtle-hover", "value": "rgba(0, 0, 0, 0.19)" },
{ "name": "--a-border-on-inverted", "value": "rgba(229, 229, 229, 1)" },
{ "name": "--a-border-on-inverted-subtle", "value": "rgba(89, 89, 89, 1)" }
],
"semantic-border-action": [
{ "name": "--a-border-action", "value": "rgba(0, 103, 197, 1)" },
{ "name": "--a-border-action-selected", "value": "rgba(0, 91, 130, 1)" },
{ "name": "--a-border-selected", "value": "rgba(0, 103, 197, 1)" },
{ "name": "--a-border-selected", "value": "rgba(0, 103, 197, 1)" }
],
"semantic-border-status": [
{ "name": "--a-border-success", "value": "rgba(6, 137, 58, 1)" },
{ "name": "--a-border-danger", "value": "rgba(195, 0, 0, 1)" },
{ "name": "--a-border-warning", "value": "rgba(199, 115, 0, 1)" },
{ "name": "--a-border-info", "value": "rgba(54, 141, 168, 1)" },
{ "name": "--a-border-on-inverted", "value": "rgba(229, 229, 229, 1)" },
{ "name": "--a-border-on-inverted-subtle", "value": "rgba(89, 89, 89, 1)" },
{ "name": "--a-border-info", "value": "rgba(54, 141, 168, 1)" }
],
"semantic-border-focus": [
{ "name": "--a-border-focus", "value": "rgba(0, 52, 125, 1)" },
{
"name": "--a-border-focus-on-inverted",
"value": "rgba(153, 195, 255, 1)"
},
}
],
"semantic-border-alt": [
{ "name": "--a-border-alt-1", "value": "rgba(130, 105, 162, 1)" },
{ "name": "--a-border-alt-2", "value": "rgba(127, 137, 0, 1)" },
{ "name": "--a-border-alt-3", "value": "rgba(0, 91, 130, 1)" }
@@ -241,7 +249,7 @@
{ "name": "--a-text-on-alt-2", "value": "rgba(38, 38, 38, 1)" },
{ "name": "--a-text-on-alt-3", "value": "rgba(255, 255, 255, 1)" }
],
"semantic-surface": [
"semantic-surface-default": [
{ "name": "--a-surface-default", "value": "rgba(255, 255, 255, 1)" },
{ "name": "--a-surface-hover", "value": "rgba(0, 0, 0, 0.05)" },
{ "name": "--a-surface-active", "value": "rgba(0, 0, 0, 0.1)" },
@@ -251,7 +259,9 @@
{ "name": "--a-surface-backdrop", "value": "rgba(0, 0, 0, 0.65)" },
{ "name": "--a-surface-inverted-hover", "value": "rgba(64, 64, 64, 1)" },
{ "name": "--a-surface-inverted-active", "value": "rgba(89, 89, 89, 1)" },
{ "name": "--a-surface-inverted", "value": "rgba(38, 38, 38, 1)" },
{ "name": "--a-surface-inverted", "value": "rgba(38, 38, 38, 1)" }
],
"semantic-surface-action": [
{ "name": "--a-surface-action-subtle", "value": "rgba(230, 240, 255, 1)" },
{
"name": "--a-surface-action-subtle-hover",
@@ -264,7 +274,9 @@
{
"name": "--a-surface-action-selected-hover",
"value": "rgba(0, 80, 119, 1)"
},
}
],
"semantic-surface-neutral": [
{ "name": "--a-surface-neutral-subtle", "value": "rgba(0, 0, 0, 0.05)" },
{
"name": "--a-surface-neutral-subtle-hover",
@@ -274,7 +286,9 @@
{ "name": "--a-surface-neutral", "value": "rgba(89, 89, 89, 1)" },
{ "name": "--a-surface-neutral-hover", "value": "rgba(64, 64, 64, 1)" },
{ "name": "--a-surface-neutral-selected", "value": "rgba(38, 38, 38, 1)" },
{ "name": "--a-surface-neutral-active", "value": "rgba(38, 38, 38, 1)" },
{ "name": "--a-surface-neutral-active", "value": "rgba(38, 38, 38, 1)" }
],
"semantic-surface-success": [
{ "name": "--a-surface-success-subtle", "value": "rgba(204, 241, 214, 1)" },
{
"name": "--a-surface-success-subtle-hover",
@@ -285,7 +299,9 @@
"value": "rgba(153, 222, 173, 1)"
},
{ "name": "--a-surface-success", "value": "rgba(6, 137, 58, 1)" },
{ "name": "--a-surface-success-hover", "value": "rgba(0, 124, 46, 1)" },
{ "name": "--a-surface-success-hover", "value": "rgba(0, 124, 46, 1)" }
],
"semantic-surface-danger": [
{ "name": "--a-surface-danger-subtle", "value": "rgba(255, 194, 194, 1)" },
{
"name": "--a-surface-danger-subtle-hover",
@@ -297,7 +313,9 @@
},
{ "name": "--a-surface-danger", "value": "rgba(195, 0, 0, 1)" },
{ "name": "--a-surface-danger-hover", "value": "rgba(173, 0, 0, 1)" },
{ "name": "--a-surface-danger-active", "value": "rgba(140, 0, 0, 1)" },
{ "name": "--a-surface-danger-active", "value": "rgba(140, 0, 0, 1)" }
],
"semantic-surface-warning": [
{ "name": "--a-surface-warning-subtle", "value": "rgba(255, 236, 204, 1)" },
{
"name": "--a-surface-warning-moderate",
@@ -307,14 +325,18 @@
{
"name": "--a-surface-warning-subtle-hover",
"value": "rgba(255, 215, 153, 1)"
},
}
],
"semantic-surface-info": [
{ "name": "--a-surface-info-subtle", "value": "rgba(216, 249, 255, 1)" },
{
"name": "--a-surface-info-subtle-hover",
"value": "rgba(181, 241, 255, 1)"
},
{ "name": "--a-surface-info-moderate", "value": "rgba(181, 241, 255, 1)" },
{ "name": "--a-surface-info", "value": "rgba(102, 203, 236, 1)" },
{ "name": "--a-surface-info", "value": "rgba(102, 203, 236, 1)" }
],
"semantic-surface-alt": [
{ "name": "--a-surface-alt-1", "value": "rgba(130, 105, 162, 1)" },
{ "name": "--a-surface-alt-1-subtle", "value": "rgba(224, 216, 233, 1)" },
{ "name": "--a-surface-alt-1-moderate", "value": "rgba(192, 178, 210, 1)" },
@@ -337,18 +359,22 @@
"value": "rgba(241, 241, 241, 1)"
}
],
"semantic-icon": [
"semantic-icon-defaults": [
{ "name": "--a-icon-default", "value": "rgba(38, 38, 38, 1)" },
{ "name": "--a-icon-subtle", "value": "rgba(0, 0, 0, 0.65)" },
{ "name": "--a-icon-on-neutral", "value": "rgba(255, 255, 255, 1)" },
{ "name": "--a-icon-on-inverted", "value": "rgba(255, 255, 255, 1)" },
{ "name": "--a-icon-on-inverted", "value": "rgba(255, 255, 255, 1)" }
],
"semantic-icon-action": [
{ "name": "--a-icon-action", "value": "rgba(0, 103, 197, 1)" },
{ "name": "--a-icon-action-selected", "value": "rgba(0, 91, 130, 1)" },
{
"name": "--a-icon-action-on-action-subtle",
"value": "rgba(0, 86, 180, 1)"
},
{ "name": "--a-icon-on-action", "value": "rgba(255, 255, 255, 1)" },
{ "name": "--a-icon-on-action", "value": "rgba(255, 255, 255, 1)" }
],
"semantic-icon-status": [
{ "name": "--a-icon-success", "value": "rgba(6, 137, 58, 1)" },
{ "name": "--a-icon-on-success", "value": "rgba(255, 255, 255, 1)" },
{ "name": "--a-icon-danger", "value": "rgba(195, 0, 0, 1)" },
@@ -356,11 +382,14 @@
{ "name": "--a-icon-warning", "value": "rgba(199, 115, 0, 1)" },
{ "name": "--a-icon-on-warning", "value": "rgba(38, 38, 38, 1)" },
{ "name": "--a-icon-info", "value": "rgba(35, 107, 125, 1)" },
{ "name": "--a-icon-on-info", "value": "rgba(38, 38, 38, 1)" },
{ "name": "--a-icon-on-info", "value": "rgba(38, 38, 38, 1)" }
],
"semantic-icon-alt": [
{ "name": "--a-icon-alt-1", "value": "rgba(99, 70, 137, 1)" },
{ "name": "--a-icon-alt-2", "value": "rgba(127, 137, 0, 1)" },
{ "name": "--a-icon-alt-3", "value": "rgba(51, 128, 165, 1)" }
],
"semantic-data-surface": [
{
"name": "--a-data-surface-1",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-tokens",
"version": "4.1.2",
"version": "4.1.6",
"description": "Design-tokens for NAV designsystem",
"author": "Aksel | NAV designsystem team",
"keywords": [
+3 -1
View File
@@ -5,6 +5,7 @@ ENV NODE_ENV production
WORKDIR /app
COPY aksel.nav.no/website/.next/standalone ./
COPY aksel.nav.no/website/next-logger.config.js ./
# COPY aksel.nav.no/website/package.json .
# COPY aksel.nav.no/website/.next/ .next/
# COPY aksel.nav.no/website/public/ public
@@ -14,6 +15,7 @@ COPY aksel.nav.no/website/.next/standalone ./
# COPY @navikt/ @navikt/
# CMD yarn start
ENV NODE_OPTIONS '-r next-logger'
EXPOSE 3000
CMD ["node", "aksel.nav.no/website/server.js"]
+5 -5
View File
@@ -15,11 +15,11 @@
"website"
],
"dependencies": {
"@navikt/aksel-icons": "^4.1.2",
"@navikt/ds-css": "^4.1.2",
"@navikt/ds-react": "^4.1.2",
"@navikt/ds-tailwind": "^4.1.2",
"@navikt/ds-tokens": "^4.1.2"
"@navikt/aksel-icons": "^4.1.6",
"@navikt/ds-css": "^4.1.6",
"@navikt/ds-react": "^4.1.6",
"@navikt/ds-tailwind": "^4.1.6",
"@navikt/ds-tokens": "^4.1.6"
},
"devDependencies": {
"prettier-plugin-tailwindcss": "^0.2.3"
@@ -25,20 +25,8 @@ import {
UuFeedback,
Video,
} from ".";
export const InlineCode = (props: React.HTMLAttributes<HTMLElement>) => (
<code
className="bg-surface-alt-3-subtle/50 py-05 rounded px-1 leading-normal [font-size:_calc(16em_/_18)]"
{...props}
/>
);
export const KBD = (props: React.HTMLAttributes<HTMLElement>) => (
<kbd
className="text-text-default bg-surface-default py-05 text-medium whitespace-nowrap rounded px-1 leading-normal shadow-[0_0_0_1px_var(--a-border-strong)]"
{...props}
/>
);
import { KBD } from "components/website-modules/KBD";
import { InlineCode } from "components/website-modules/InlineCode";
const serializers = {
types: {
@@ -169,7 +157,7 @@ const serializers = {
return (
<BodyLong
as="li"
className="ml-5 mb-3 max-w-[calc(theme(spacing.text)_-_1em)]"
className="mb-3 ml-5 max-w-[calc(theme(spacing.text)_-_1em)]"
>
{props.children}
</BodyLong>
@@ -1,24 +0,0 @@
import Footer from "./Footer";
import { Meta } from "@storybook/react";
import { NextDecorator } from "../../StoryDecorator";
const MetaData: Meta = {
component: Footer,
tags: ["autodocs"],
decorators: [
(Story) => (
<NextDecorator>
<Story />
</NextDecorator>
),
],
parameters: {
layout: "fullscreen",
},
};
export default MetaData;
export const FooterDemo = {
render: () => <Footer />,
};
@@ -50,7 +50,7 @@ export function Hit({
<span className="mt-4 flex gap-2 empty:mt-0">
{hit.item?.tema &&
hit.item?.tema.map((x) => (
<Tag variant="alt3" size="xsmall" key={x}>
<Tag variant="neutral-moderate" size="xsmall" key={x}>
{x}
</Tag>
))}
@@ -1,20 +1,20 @@
import { useDebounce, logSearch } from "@/utils";
import { SearchLogT, SearchResultsT, searchOptions } from "@/types";
import { logSearch, useDebounce } from "@/utils";
import { MagnifyingGlassIcon } from "@navikt/aksel-icons";
import {
Button,
Checkbox,
CheckboxGroup,
Detail,
Loader,
Search,
} from "@navikt/ds-react";
import { ChangeLogIconOutline } from "components/assets";
import { SearchLogT, searchOptions, SearchResultsT } from "@/types";
import { KBD } from "components/website-modules/KBD";
import { useRouter } from "next/router";
import React, { useCallback, useEffect, useRef, useState } from "react";
import { useCallback, useEffect, useRef, useState } from "react";
import ReactModal from "react-modal";
import { Group, GroupComponent } from "./Group";
import styles from "../header.module.css";
import { MagnifyingGlassIcon } from "@navikt/aksel-icons";
import { Group, GroupComponent } from "./Group";
/**
* https://www.figma.com/file/71Sm1h6VV23lbBbQ3CJJ9t/Aksel-v2?node-id=1861%3A186079&t=ARKgZcA6B7ysmG3V-0
@@ -189,7 +189,7 @@ export const GlobalSearch = () => {
};
return (
<div className="z-[1050] mr-4 ml-auto flex justify-center lg:mr-0 lg:ml-0">
<div className="z-[1050] ml-auto mr-4 flex justify-center lg:ml-0 lg:mr-0">
<Button
variant="primary"
className="hover:bg-deepblue-700 bg-deepblue-600 focus-visible:shadow-focus-gap h-11 focus:shadow-none"
@@ -215,12 +215,21 @@ export const GlobalSearch = () => {
overlayClassName={styles.modalOverlaySearch}
>
<div className="search-grid-wrapper relative mx-auto max-w-4xl gap-4 gap-x-8 py-24">
<button
className="focus-visible:shadow-focus hover:bg-surface-neutral-subtle-hover absolute top-8 right-4 flex items-center justify-center rounded py-3 px-2 text-lg focus:outline-none"
onClick={() => handleClose()}
{/* <button
className="focus-visible:shadow-focus hover:bg-surface-neutral-subtle-hover absolute right-4 top-8 flex items-center justify-center gap-2 rounded px-2 py-3 text-lg focus:outline-none"
>
Lukk søk <KBD>ESC</KBD>
</button>
<span>Lukk søk</span>
</button> */}
<Button
className="absolute right-4 top-8"
variant="tertiary-neutral"
icon={<KBD>ESC</KBD>}
onClick={() => handleClose()}
iconPosition="right"
>
Lukk søk
</Button>
<div className="search-grid-filter mt-8">
<CheckboxGroup legend="Filter" onChange={setTags}>
{Object.entries(searchOptions)
@@ -247,8 +256,8 @@ export const GlobalSearch = () => {
<form role="search" onSubmit={(e) => e.preventDefault()}>
<Search
label={
<span className="flex items-center">
Søk i hele Aksel{" "}
<span className="flex items-center gap-2">
<span>Søk i hele Aksel</span>
{os === "mac" ? <KBD>CMD + B</KBD> : <KBD>CTRL + B</KBD>}
</span>
}
@@ -359,14 +368,3 @@ export const GlobalSearch = () => {
</div>
);
};
function KBD({ children }: { children: React.ReactNode }) {
return (
<Detail
as="kbd"
className="bg-surface-neutral-subtle-hover ml-2 hidden rounded px-2 font-sans font-semibold uppercase md:inline-block"
>
{children}
</Detail>
);
}
@@ -1,7 +1,7 @@
import { AkselSidebarT } from "@/types";
import { logNav } from "@/utils";
import { ChevronDownIcon } from "@navikt/aksel-icons";
import { BodyShort, Detail, Tag } from "@navikt/ds-react";
import { Detail, Tag } from "@navikt/ds-react";
import cl from "clsx";
import Link from "next/link";
import { useRouter } from "next/router";
@@ -17,61 +17,52 @@ const NavItem = ({
}) => {
const isActive = asPath === `/${link.slug}`;
return (
<li
className={cl(
"focus-within:shadow-focus peer relative rounded-sm pl-2 before:absolute before:left-0 before:z-[-1]",
{
"before:border-l-border-action-selected before:top-1/2 before:h-6 before:-translate-y-1/2 before:rounded-full before:border-l-[4px]":
isActive,
"before:h-full before:rounded-full before:border-l before:border-l-gray-200 hover:before:top-1/2 hover:before:h-6 hover:before:-translate-y-1/2 hover:before:border-l-2 hover:before:border-l-gray-400":
!isActive,
}
)}
>
<Link href={`/${link.slug}`} passHref legacyBehavior>
<BodyShort
as="a"
size="small"
onClick={(e) => {
logNav(
"meny",
window.location.pathname,
e.currentTarget.getAttribute("href")
);
}}
className={cl(
"hover:text-deepblue-800 relative flex overflow-hidden px-2 py-[6px] no-underline focus:outline-none",
{
"text-deepblue-800 font-semibold": isActive,
"text-text-subtle": !isActive,
}
)}
>
{link.heading}
<span className="ml-auto capitalize">
{link.tag && ["deprecated", "beta", "new"].includes(link.tag) && (
<Tag
size="xsmall"
variant={
link.tag === "beta"
? "alt1"
: link.tag === "deprecated"
? "neutral"
: "info"
}
className={cl({
"border-violet-300 bg-violet-50": link.tag === "beta",
})}
>
{link.tag === "new"
? "ny"
<li>
<Link
href={`/${link.slug}`}
onClick={(e) => {
logNav(
"meny",
window.location.pathname,
e.currentTarget.getAttribute("href")
);
}}
className={cl(
"hover:text-deepblue-800 focus-visible:shadow-focus text-medium relative flex overflow-hidden rounded-sm py-1 pl-4 pr-2 leading-snug before:rounded-full hover:before:transition-colors focus:outline-none",
{
"before:border-l-border-action-selected before:absolute before:left-0 before:top-1/2 before:h-6 before:-translate-y-1/2 before:border-l-[4px]":
isActive,
"text-deepblue-800 font-semibold": isActive,
"text-text-subtle": !isActive,
"before:absolute before:left-0 before:h-full before:border-l before:border-l-gray-200 hover:before:top-1/2 hover:before:h-6 hover:before:-translate-y-1/2 hover:before:border-l-2 hover:before:border-l-gray-400":
!isActive,
}
)}
>
{link.heading}
<span className="ml-auto capitalize">
{link.tag && ["deprecated", "beta", "new"].includes(link.tag) && (
<Tag
size="xsmall"
variant={
link.tag === "beta"
? "alt1"
: link.tag === "deprecated"
? "Avviklet"
: link.tag}
</Tag>
)}
</span>
</BodyShort>
? "neutral"
: "info"
}
className={cl({
"border-violet-300 bg-violet-50": link.tag === "beta",
})}
>
{link.tag === "new"
? "ny"
: link.tag === "deprecated"
? "Avviklet"
: link.tag}
</Tag>
)}
</span>
</Link>
</li>
);
@@ -88,10 +79,10 @@ const Dropdown = ({
const { asPath } = useRouter();
return (
<li className="sidebar-dropdown w-full" data-open={open}>
<li className="peer w-full peer-data-[open=true]:mt-6" data-open={open}>
<button
onClick={() => setOpen((x) => !x)}
className="min-h-8 text-text-subtle hover:text-deepblue-800 group z-10 flex w-full cursor-pointer items-center justify-between pr-2 focus:outline-none"
className="min-h-8 text-text-subtle hover:text-deepblue-800 group z-10 flex w-full cursor-pointer items-center justify-between focus:outline-none"
aria-expanded={open}
>
<Detail
@@ -109,16 +100,11 @@ const Dropdown = ({
</Detail>
</button>
<ul hidden={!open} className="px-2">
<ul hidden={!open} className="pl-2">
{links.map((z) => (
<NavItem link={z} key={z?.heading} asPath={asPath} />
))}
</ul>
<style jsx>{`
.sidebar-dropdown[data-open="true"] + .sidebar-dropdown {
margin-top: var(--a-spacing-6);
}
`}</style>
</li>
);
};
@@ -135,10 +121,10 @@ export const Sidebar = ({
return (
<div
data-testid="ds-sidebar"
className="toc-ignore w-sidebar bg-surface-default z-[1002] hidden shrink-0 self-start pb-4 md:block"
className="toc-ignore w-sidebar bg-surface-default z-[1002] hidden shrink-0 self-start overflow-x-auto pb-8 pl-6 pr-2 md:block"
>
<nav aria-label={kategori} className={cl("overflow-x-auto")}>
<ul className="pb-4 pl-6">
<nav aria-label={kategori}>
<ul>
{sections.map((kat) => (
<Dropdown links={kat.pages} title={kat.title} key={kat.title} />
))}
@@ -3,37 +3,36 @@ import { withErrorBoundary } from "@/error-boundary";
import { urlFor } from "@/sanity/interface";
import { DoDontT } from "@/types";
import {
CheckmarkCircleFillIcon,
ExclamationmarkTriangleFillIcon,
XMarkOctagonFillIcon,
CheckmarkIcon,
ExclamationmarkIcon,
XMarkIcon,
} from "@navikt/aksel-icons";
import { BodyShort } from "@navikt/ds-react";
import cl from "clsx";
import React from "react";
const GetIcon = (s: string) => {
switch (s) {
case "do":
return (
<CheckmarkCircleFillIcon
<CheckmarkIcon
aria-hidden
fontSize="1.5rem"
fontSize="2rem"
className="flex-shrink-0 text-green-500"
/>
);
case "dont":
return (
<XMarkOctagonFillIcon
<XMarkIcon
aria-hidden
fontSize="1.5rem"
fontSize="2rem"
className="flex-shrink-0 text-red-500"
/>
);
case "warning":
return (
<ExclamationmarkTriangleFillIcon
<ExclamationmarkIcon
aria-hidden
fontSize="1.5rem"
fontSize="2rem"
className="flex-shrink-0 text-orange-500"
/>
);
@@ -42,42 +41,56 @@ const GetIcon = (s: string) => {
}
};
const getText = (s: string) => {
switch (s) {
case "do":
return "Do: ";
case "dont":
return "Don't: ";
case "warning":
return "Fare på ferde: ";
default:
return "";
}
};
const Element = ({ block }: { block: DoDontT["blokker"][number] }) => {
if (!block.picture) return null;
return (
<figure
className={cl("sm:min-w-80 flex min-w-full flex-1 flex-col rounded-t", {
className={cl("sm:min-w-80 flex min-w-full flex-1 flex-col", {
"basis-full": block?.fullwidth,
"max-w-sm": !block?.fullwidth,
})}
>
<img
className="ring-border-subtle rounded-t bg-gray-50 ring-1"
alt={block.alt}
loading="lazy"
decoding="async"
src={urlFor(block.picture).auto("format").url()}
/>
<div
className={cl(
"z-10 -ml-[1px] w-[calc(100%_+_2px)] rounded-b border-t-8",
"relative z-10 -ml-[1px] w-[calc(100%_+_2px)] border-t-4",
{
"border-t-border-success": block.variant === "do",
"border-t-border-danger": block.variant === "dont",
"border-t-surface-warning": block.variant === "warning",
}
)}
aria-hidden
>
<span className="absolute left-[10px] z-10 translate-y-2">
{GetIcon(block.variant)}
</span>
</div>
<img
className="ring-border-subtle bg-gray-50 ring-1"
alt={block.alt}
loading="lazy"
decoding="async"
src={urlFor(block.picture).auto("format").url()}
/>
<figcaption data-variant={block.variant}>
<div className="mt-3">
{block.description && (
<BodyShort
size="small"
as="span"
className="inline-flex items-center gap-2"
>
{GetIcon(block.variant)}
{block.description}
<BodyShort size="small" as="span">
<span className="font-semibold">{getText(block.variant)}</span>
<span>{block.description}</span>
</BodyShort>
)}
</div>
@@ -1,16 +1,9 @@
import { withErrorBoundary } from "@/error-boundary";
import { UUTableT } from "@/types";
import cl from "clsx";
import React from "react";
import { KBD } from "components/website-modules/KBD";
const KBD = (props: React.HTMLAttributes<HTMLElement>) => (
<kbd
className={cl(
"mx-05 my-0 inline-block min-w-[2rem] rounded-md border border-gray-300 bg-gray-100 py-[1px] px-2 text-center font-mono text-sm text-gray-900"
)}
{...props}
/>
);
import { AkselTable, AkselTableRow } from "components/website-modules/Table";
import React from "react";
const UuSeksjon = ({ node }: { node: UUTableT }) => {
if (!node || !node?.tastatur) {
@@ -18,7 +11,7 @@ const UuSeksjon = ({ node }: { node: UUTableT }) => {
}
const getKey = (s: string) => (
<span className="flex w-full flex-wrap gap-x-1 gap-y-2">
<span className="my-1 flex w-full flex-wrap gap-x-1 gap-y-2">
{s
.trim()
.split(" ")
@@ -32,27 +25,14 @@ const UuSeksjon = ({ node }: { node: UUTableT }) => {
);
return (
<table className="mb-7 w-full border-separate border-spacing-0 rounded border border-gray-300">
<thead>
<tr className="rounded-t">
<td className="rounded-tl bg-gray-50 p-2 ">Kommando</td>
<td className="rounded-tr bg-gray-50 p-2 ">Interaksjon</td>
</tr>
</thead>
<tbody className="">
{node.tastatur.map((x) => (
<tr
key={x._key}
className="peer border-b border-t border-gray-300 text-base last-of-type:rounded-b"
>
<td className="border-t border-r border-gray-300 p-2">
{getKey(x.key)}
</td>
<td className="border-t border-gray-300 p-2">{x.action}</td>
</tr>
))}
</tbody>
</table>
<AkselTable th={[{ text: "Kommando" }, { text: "Interaksjon" }]}>
{node.tastatur.map((x) => (
<AkselTableRow
key={x._key}
tr={[{ text: getKey(x.key) }, { text: x.action }]}
/>
))}
</AkselTable>
);
};
@@ -4,6 +4,7 @@ import { ChevronDownCircleIcon } from "@navikt/aksel-icons";
import core from "@navikt/ds-css/tokens.json";
import { BodyLong, CopyButton, Label, Link } from "@navikt/ds-react";
import cl from "classnames";
import { AkselTable, AkselTableRow } from "components/website-modules/Table";
import NextLink from "next/link";
import { useState } from "react";
@@ -27,27 +28,13 @@ const TokenTable = ({ node }: { node: TokenTableT }) => {
!open && showMore,
})}
>
<table className="border-border-divider w-full border-separate border-spacing-0 rounded-t border">
<thead>
<tr className="rounded-t">
<td className="rounded-tl bg-gray-50 p-2 ">Token</td>
<td className="rounded-tr bg-gray-50 p-2 ">Fallback</td>
</tr>
</thead>
<tbody>
{Object.entries(tokens).map(([key, val]) => (
<tr
key={key}
className="peer border-b border-t border-gray-300 font-mono text-sm last-of-type:rounded-b"
>
<td className="border-r border-t border-gray-300 p-2">{key}</td>
<td className="border-t border-gray-300 p-2">{val}</td>
</tr>
))}
</tbody>
</table>
<AkselTable th={[{ text: "Token" }, { text: "Fallback" }]}>
{Object.entries(tokens).map(([key, val]) => (
<AkselTableRow key={key} tr={[{ text: key }, { text: val }]} />
))}
</AkselTable>
{(open || !showMore) && (
<div className="border-border-divider bg-surface-neutral-subtle relative w-full rounded-b border border-t-0 p-2 pr-14">
<div className="border-border-subtle bg-surface-default relative -mt-8 w-full rounded-b border border-t-0 p-2 pr-14">
<CopyButton
copyText={Object.entries(tokens).reduce(
(prev, cur) =>
@@ -82,6 +82,7 @@ const ComponentExamples = ({ node }: { node: CodeExapmplesT }) => {
{node.dir.filer.map((fil) => {
return (
<Chips.Toggle
checkmark={false}
key={fil._key}
value={fil.navn}
selected={active === fil.navn}
@@ -46,8 +46,9 @@ const CodeSnippet = ({
>
<CopyButton
data-theme="dark"
size="small"
copyText={code.code}
className={cl(style.copybutton, "absolute top-2 right-2 z-10")}
className={cl(style.copybutton, "absolute right-2 top-2 z-10")}
/>
<Highlight
code={code.code}
@@ -1,45 +0,0 @@
import { TipsT } from "@/types";
import Tips from "./index";
export default {
title: "Components/Tips",
component: Tips,
};
const mockData: TipsT = {
_key: "eb522d23896b",
body: [
{
_key: "86a3e733e9bb",
_type: "block",
children: [
{
_key: "5d65a8d0f1760",
_type: "span",
marks: [],
text: "Cupidatat nostrud occaecat incididunt elit adipisicing consequat eu ex anim qui officia mollit.",
},
{
_key: "5d65a8d0f1760",
_type: "span",
marks: [],
text: "Sint incididunt non incididunt ipsum ad esse officia.",
},
],
markDefs: [],
style: "normal",
},
],
eksperiment: false,
};
export const TipsDemo = () => <Tips node={mockData as any} />;
export const TipsDemoAksel = () => (
<div className="aksel-artikkel bg-surface-subtle">
<Tips node={mockData as any} />
</div>
);
export const TipsDemoExperiment = () => (
<Tips node={{ ...mockData, eksperiment: true } as any} />
);
@@ -0,0 +1,49 @@
import { CheckmarkIcon, ClipboardIcon } from "@navikt/aksel-icons";
import { useEffect, useRef, useState } from "react";
import cl from "clsx";
export const Copy = ({ text, copyText }) => {
const [active, setActive] = useState(false);
const [canfade, setCanfade] = useState(false);
const timeoutRef = useRef<number>();
useEffect(() => {
return () => {
timeoutRef.current && clearTimeout(timeoutRef.current);
};
}, []);
const handleClick = () => {
timeoutRef.current && clearTimeout(timeoutRef.current);
setCanfade(true);
navigator.clipboard.writeText(copyText);
setActive(true);
timeoutRef.current = window.setTimeout(() => {
setActive(false);
}, 2000);
};
return (
<button
type="button"
aria-live="polite"
className="py-05 focus-visible:shadow-focus min-h-8 text-medium hover:bg-surface-neutral-subtle-hover group rounded px-1 leading-none focus:outline-none"
onClick={handleClick}
>
<span className="inline-flex flex-row-reverse items-center gap-1">
<span>
{active ? (
<CheckmarkIcon title="Kopiert" className="animate-textbounce" />
) : (
<ClipboardIcon
title="Kopier css-variabel"
className={cl(canfade && "animate-fadeIn")}
/>
)}
</span>
<span aria-live="polite">{text}</span>
</span>
</button>
);
};
@@ -1,70 +0,0 @@
import { CheckmarkIcon, FilesIcon } from "@navikt/aksel-icons";
import cl from "clsx";
import copystring from "copy-to-clipboard";
import { useEffect, useRef, useState } from "react";
export const CopyToken = ({ val }: { val: string }) => {
const timerRef = useRef(null);
const [copyTimer, setCopyTimer] = useState(false);
const [done, setDone] = useState(true);
const copyToken = () => {
copystring(`var(${val})`);
if (done) {
clearTimeout(timerRef.current);
setCopyTimer(true);
setDone(false);
timerRef.current = setTimeout(() => {
setCopyTimer(false);
setDone(true);
}, 2000);
}
};
useEffect(() => {
return () => clearTimeout(timerRef.current);
}, []);
return (
<button
onClick={() => copyToken()}
className="bg-surface-subtle z-1000 hover:text-text-subtle focus-visible:border-border-focus border-surface-default group relative h-8 w-full overflow-x-hidden overflow-y-hidden whitespace-nowrap rounded border-2 font-mono text-sm focus-visible:outline-none"
aria-label={
copyTimer ? "kopierte token" : `kopier ${val.replace("--a-", "")}`
}
>
<span
className={cl("flex h-7 w-full items-center justify-between px-2", {
"animate-popout -translate-y-full": copyTimer,
})}
>
<span aria-hidden>{val}</span>
<span className="text-text-subtle bg-surface-subtle group-hover:text-text-default text-md absolute right-2 flex h-7 translate-x-3/4 items-center gap-1 px-1 shadow-[-7px_0_8px_0px_var(--a-surface-subbg-surface-subtle)] transition-transform duration-200 group-hover:translate-x-0">
<FilesIcon aria-hidden className="h-4 w-4 flex-shrink-0" />
<span className="opacity-0 transition-opacity duration-300 group-hover:opacity-100">
Kopier
</span>
</span>
</span>
<span
className={cl(
"bg-surface-action-selected text-md text-text-on-action flex h-7 w-full px-2 font-sans text-sm",
{ "animate-popup translate-y-[-100%]": copyTimer }
)}
aria-hidden
>
<span
className={cl("flex w-full items-center justify-center gap-1", {
"animate-textbounce": copyTimer,
})}
>
<CheckmarkIcon aria-hidden className="h-5 w-5 flex-shrink-0" />
Kopiert
</span>
</span>
</button>
);
};
@@ -1,77 +0,0 @@
import { Detail } from "@navikt/ds-react";
import { CopyToken } from "./CopyToken";
export const Frame = ({
tokens,
styles,
element: Element,
showHex,
}: {
tokens: { name: string; value: string; description?: string }[];
styles?: string;
element?: ({ token, name }: { token: string; name?: string }) => JSX.Element;
showHex?: boolean;
}) => {
const hasDescription = !!tokens.find((x) => x?.description);
return (
<table className="w-full">
<thead className="sr-only">
<tr>
<td />
<th>Token navn</th>
<th>Verdi</th>
{hasDescription && <th>Beskrivelse</th>}
</tr>
</thead>
<tbody className="component-token-grid grid grid-cols-[repeat(auto-fill,_minmax(min(20rem,_100%),_1fr))] gap-4">
{tokens.map((c) => (
<tr
key={c.name}
className="ring-border-subtle flex flex-col justify-start rounded-md p-3 align-top ring-1"
>
<td className="component-checkered-bg rounded-md p-0">
{Element ? (
<Element token={c.value} name={c.name} />
) : (
<div
style={{ [styles]: c.value }}
className="min-h-16 shadow-small h-full w-full rounded-md"
aria-hidden
/>
)}
</td>
<td className="mt-3 w-full overflow-x-hidden">
<CopyToken val={c.name} />
</td>
<td className="mt-2 font-mono text-sm tracking-tighter">
{c.value}
</td>
<Detail as="td" className="mt-1">
{showHex ? getHex(c.value) : c.description}
</Detail>
</tr>
))}
</tbody>
</table>
);
};
function getHex(value: string) {
return RGBAToHexA(value.replace(", 1)", ""));
}
/* https://stackoverflow.com/a/73401564 */
function RGBAToHexA(rgba, forceRemoveAlpha = false) {
return (
"#" +
rgba
.replace(/^rgba?\(|\s+|\)$/g, "") // Get's rgba / rgb string values
.split(",") // splits them at ","
.filter((string, index) => !forceRemoveAlpha || index !== 3)
.map((string) => parseFloat(string)) // Converts them to numbers
.map((number, index) => (index === 3 ? Math.round(number * 255) : number)) // Converts alpha to 255 number
.map((number) => number.toString(16)) // Converts numbers to hex
.map((string) => (string.length === 1 ? "0" + string : string)) // Adds 0 when length of one number is 1
.join("")
); // Puts the array to togehter to a string
}
@@ -0,0 +1,20 @@
import React from "react";
import cl from "clsx";
export const Grid = ({
children,
stacked = false,
}: {
children: React.ReactNode;
stacked?: boolean;
}) => (
<div
className={cl("mt-8 grid", {
"grid-cols-[repeat(auto-fit,_minmax(16rem,_1fr))] gap-6 xl:grid-cols-3":
!stacked,
"gap-8": stacked,
})}
>
{children}
</div>
);
@@ -1,126 +1,62 @@
import {
LaptopIcon,
MobileIcon,
MobileSmallIcon,
MonitorIcon,
TabletIcon,
} from "@navikt/aksel-icons";
import docs from "@navikt/ds-tokens/docs.json";
import { Frame } from "../Frame";
import { AkselTable, AkselTableRow } from "components/website-modules/Table";
export const BreakpointsView = ({ cat }: { cat: string }) => {
const breakpoints = docs[cat];
return (
<Frame
tokens={breakpoints}
element={({ name }: { token: string; name?: string }) => {
const Svg = getSvg(name);
return (
<div
className="min-h-16 bg-surface-default flex h-full w-full items-center justify-start rounded-md px-4 text-5xl font-semibold"
aria-hidden
>
{Svg}
</div>
);
}}
/>
<AkselTable
withCopy
th={[
{ text: "Enhet" },
{ text: "Verdi" },
{ text: "Media queries", hideOnSm: true },
{ text: "Bruk" },
]}
>
{breakpoints.map((x) => (
<AkselTableRow
key={x.name}
tr={[
{ text: getSvg(x.name) },
{ text: x.value },
{ text: x.description, hideOnSm: true },
{
text:
Number(x.value.replace("px", "")) % 2 === 0
? "Mobile first"
: "Desktop first",
},
]}
copyText={x.name}
/>
))}
</AkselTable>
);
};
function getSvg(token: string) {
switch (true) {
case token.includes("xs"):
return (
<svg
width="1em"
height="1em"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
focusable={false}
aria-hidden
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M7.75 5.77778C7.75 5.16382 8.20527 4.75 8.66667 4.75H15.3333C15.7947 4.75 16.25 5.16382 16.25 5.77778V18.2222C16.25 18.8362 15.7947 19.25 15.3333 19.25H8.66667C8.20527 19.25 7.75 18.8362 7.75 18.2222V5.77778ZM8.66667 3.25C7.28712 3.25 6.25 4.42806 6.25 5.77778V18.2222C6.25 19.5719 7.28712 20.75 8.66667 20.75H15.3333C16.7129 20.75 17.75 19.5719 17.75 18.2222V5.77778C17.75 4.42806 16.7129 3.25 15.3333 3.25H8.66667ZM12 16.75C11.5858 16.75 11.25 17.0858 11.25 17.5C11.25 17.9142 11.5858 18.25 12 18.25H12.01C12.4242 18.25 12.76 17.9142 12.76 17.5C12.76 17.0858 12.4242 16.75 12.01 16.75H12Z"
fill="#262626"
/>
</svg>
);
return <MobileSmallIcon title="Mobile small" fontSize="2.5rem" />;
case token.includes("sm"):
return (
<svg
width="1em"
height="1em"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
focusable={false}
aria-hidden
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M6.75 5C6.75 4.30964 7.30964 3.75 8 3.75H16C16.6904 3.75 17.25 4.30964 17.25 5V19C17.25 19.6904 16.6904 20.25 16 20.25H8C7.30964 20.25 6.75 19.6904 6.75 19V5ZM8 2.25C6.48122 2.25 5.25 3.48122 5.25 5V19C5.25 20.5188 6.48122 21.75 8 21.75H16C17.5188 21.75 18.75 20.5188 18.75 19V5C18.75 3.48122 17.5188 2.25 16 2.25H8ZM11.5 4.75C11.0858 4.75 10.75 5.08579 10.75 5.5C10.75 5.91421 11.0858 6.25 11.5 6.25H12.5C12.9142 6.25 13.25 5.91421 13.25 5.5C13.25 5.08579 12.9142 4.75 12.5 4.75H11.5Z"
fill="#262626"
/>
</svg>
);
return <MobileIcon title="Mobile regular" fontSize="2.5rem" />;
case token.includes("md"):
return (
<svg
width="1em"
height="1em"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
focusable={false}
aria-hidden
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M3.75 6C3.75 5.30964 4.30964 4.75 5 4.75H19C19.6904 4.75 20.25 5.30964 20.25 6V18C20.25 18.6904 19.6904 19.25 19 19.25H5C4.30964 19.25 3.75 18.6904 3.75 18V6ZM5 3.25C3.48122 3.25 2.25 4.48122 2.25 6V18C2.25 19.5188 3.48122 20.75 5 20.75H19C20.5188 20.75 21.75 19.5188 21.75 18V6C21.75 4.48122 20.5188 3.25 19 3.25H5ZM10.5 5.75C10.0858 5.75 9.75 6.08579 9.75 6.5C9.75 6.91421 10.0858 7.25 10.5 7.25H13.5C13.9142 7.25 14.25 6.91421 14.25 6.5C14.25 6.08579 13.9142 5.75 13.5 5.75H10.5Z"
fill="#262626"
/>
</svg>
);
return <TabletIcon title="Tablet" fontSize="2.5rem" />;
case token.includes("lg"):
return (
<svg
width="1em"
height="1em"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
focusable={false}
aria-hidden
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M5.5 4.25C4.5335 4.25 3.75 5.0335 3.75 6V15C3.75 15.9665 4.5335 16.75 5.5 16.75H18.5C19.4665 16.75 20.25 15.9665 20.25 15V6C20.25 5.0335 19.4665 4.25 18.5 4.25H5.5ZM5.25 6C5.25 5.86193 5.36193 5.75 5.5 5.75H18.5C18.6381 5.75 18.75 5.86193 18.75 6V15C18.75 15.1381 18.6381 15.25 18.5 15.25H5.5C5.36193 15.25 5.25 15.1381 5.25 15V6ZM3 18.25C2.58579 18.25 2.25 18.5858 2.25 19C2.25 19.4142 2.58579 19.75 3 19.75H21C21.4142 19.75 21.75 19.4142 21.75 19C21.75 18.5858 21.4142 18.25 21 18.25H3Z"
fill="#262626"
/>
</svg>
);
return <LaptopIcon title="Laptop" fontSize="2.5rem" />;
case token.includes("xl"):
return (
<svg
width="1em"
height="1em"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
focusable={false}
aria-hidden
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M2.25 4.5C2.25 3.80964 2.80964 3.25 3.5 3.25H20.5C21.1904 3.25 21.75 3.80964 21.75 4.5V15.5C21.75 16.1904 21.1904 16.75 20.5 16.75H12.75V19.25H19C19.4142 19.25 19.75 19.5858 19.75 20C19.75 20.4142 19.4142 20.75 19 20.75H6C5.58579 20.75 5.25 20.4142 5.25 20C5.25 19.5858 5.58579 19.25 6 19.25H11.25V16.75H3.5C2.80964 16.75 2.25 16.1904 2.25 15.5V4.5ZM3.75 4.75V15.25H20.25V4.75H3.75Z"
fill="#262626"
/>
</svg>
);
return <MonitorIcon title="Dekstop" fontSize="2.5rem" />;
default:
return null;
@@ -1,71 +1,59 @@
import docs from "@navikt/ds-tokens/docs.json";
import { Frame } from "../Frame";
const text = "The quick brown fox jumps over the lazy dog";
import { sanitizeName } from "../utilities";
import { AkselTable, AkselTableRow } from "components/website-modules/Table";
export const FontView = ({ cat }: { cat: string }) => {
const shapes = docs[cat];
const fonts = docs[cat];
return (
<Frame
tokens={shapes}
styles="borderRadius"
element={({ token, name }: { token: string; name?: string }) => {
if (name.includes("font-family")) {
return (
<div
className="min-h-16 bg-surface-default flex h-full w-full items-end rounded-md px-4 text-xl"
aria-hidden
>
{text}
</div>
);
}
if (name.includes("font-weight")) {
return (
<div
className="min-h-16 bg-surface-default flex h-full w-full items-end rounded-md px-4 text-xl"
aria-hidden
style={{
fontWeight: token,
}}
>
{text}
</div>
);
}
if (name.includes("font-line-height")) {
return (
<div className="bg-surface-default">
<div
className="min-h-16 flex h-full max-w-xs items-end rounded-md px-4 text-xl"
aria-hidden
style={{
lineHeight: token,
}}
>
{text}
</div>
</div>
);
}
if (name.includes("font-size")) {
return (
<div
className="min-h-16 bg-surface-default flex h-full w-full items-end rounded-md px-4 text-xl"
aria-hidden
style={{
fontSize: token,
fontWeight: name.includes("size-heading") ? "600" : "400",
lineHeight: 1.33,
}}
>
{text}
</div>
);
}
return null;
}}
/>
<AkselTable
withCopy
th={[
{ text: "Token" },
{ text: "Verdi" },
{ text: "Demo", sronly: true },
]}
>
{fonts.map((x) => (
<AkselTableRow
key={x.name}
tr={[
{ text: sanitizeName(x.name.replace("--a-font-", "")) },
{ text: x.value },
{ text: getDemoCell(x) },
]}
copyText={x.name}
/>
))}
</AkselTable>
);
};
function getDemoCell({ value, name }: { value: string; name: string }) {
switch (true) {
case name.includes("weight"):
return <span style={{ fontWeight: value }}>Foreldrepenger</span>;
case name.includes("line-height"):
return (
<span style={{ lineHeight: value }}>
Hello <br />
World
</span>
);
case name.includes("size-heading"):
return (
<span
className="leading-none"
style={{ fontSize: value, fontWeight: value }}
>
Aa
</span>
);
case name.includes("size"):
return <span style={{ fontSize: value }}>Aa</span>;
default:
return <span style={{ fontSize: value }}>Foreldrepenger</span>;
}
}
@@ -1,9 +1,35 @@
import docs from "@navikt/ds-tokens/docs.json";
import { Frame } from "../Frame";
import { Grid } from "../Grid";
import { getColorString, sanitizeName } from "../utilities";
import { Copy } from "../Copy";
export const GlobalView = ({ cat }: { cat: string }) => {
const colors = docs[cat];
return <Frame tokens={colors} styles="background" showHex />;
const colors: { name: string; value: string }[] = docs[cat];
return (
<Grid>
{colors.map((x) => {
return (
<div key={x.name} id={x.name} className="z-0 flex w-fit items-center">
<div
style={{
background: `var(${x.name})`,
boxShadow: `inset 0 2px 4px 0 rgba(0,0,0,0.06)`,
}}
className="mr-3 grid h-16 w-16 place-content-center rounded-lg"
>
<div className="component-checkered-bg z-[-1] h-16 w-16" />
</div>
<dl className="grid h-full">
<dt className="inline-flex items-center gap-2">
<Copy text={sanitizeName(x.name)} copyText={x.name} />
</dt>
<dd className="text-text-subtle text-medium mt-auto">
{getColorString(x.value)}
</dd>
</dl>
</div>
);
})}
</Grid>
);
};
@@ -1,99 +1,311 @@
import { PersonCircleIcon } from "@navikt/aksel-icons";
import docs from "@navikt/ds-tokens/docs.json";
import Link from "next/link";
import color from "tinycolor2";
import { Frame } from "../Frame";
import { Copy } from "../Copy";
import { Grid } from "../Grid";
import { getColorString, getGlobalReference, sanitizeName } from "../utilities";
export const SemanticView = ({ cat }: { cat: string }) => {
const colors = docs[cat];
if (cat === "semantic-text") {
if (cat.startsWith("semantic-text")) {
return (
<Frame
tokens={colors}
styles="color"
showHex
element={({ token }: { token: string }) => {
const c = color(token);
const isLigth = c.getLuminance() > 0.9;
<Grid>
{colors.map((x) => {
const ref = getGlobalReference(x.value);
const c = color(x.value);
const isLight = c.getLuminance() > 0.9;
return (
<div
className="min-h-16 flex h-full w-full items-end rounded-md px-4 text-5xl font-semibold"
aria-hidden
style={{
color: token,
background: isLigth
? `var(--a-surface-inverted)`
: `var(--a-surface-default)`,
}}
>
Aa
</div>
);
}}
/>
);
}
if (cat === "semantic-icon") {
return (
<Frame
tokens={colors}
styles="color"
showHex
element={({ token }: { token: string }) => {
const c = color(token);
const isLigth = c.getLuminance() > 0.9;
return (
<div
className="min-h-16 flex h-full w-full items-center justify-center rounded-md px-4 text-4xl font-semibold"
aria-hidden
style={{
color: token,
background: isLigth
? `var(--a-surface-inverted)`
: `var(--a-surface-default)`,
}}
>
<PersonCircleIcon aria-hidden />
</div>
);
}}
/>
);
}
if (cat === "semantic-border" || cat === "semantic-data-border") {
return (
<Frame
tokens={colors}
styles="color"
showHex
element={({ token }: { token: string }) => {
const c = color(token);
const isLigth = c.getLuminance() > 0.7;
return (
<div
className="min-h-16 flex h-full w-full items-center justify-center rounded-md px-4 text-5xl font-semibold"
aria-hidden
style={{
background: isLigth
? `var(--a-surface-inverted)`
: `var(--a-surface-default)`,
}}
>
<div key={x.name} id={x.name} className="flex w-fit items-center">
<div
className="h-12 w-full rounded-md"
style={{
border: `2px solid ${token}`,
background: isLight ? `var(--a-surface-inverted)` : undefined,
color: x.value,
boxShadow: `inset 0 2px 4px 0 rgba(0,0,0,0.06)`,
}}
/>
className="mr-3 grid h-16 w-16 place-content-center rounded-lg text-2xl leading-none"
>
Aa
</div>
<dl className="grid h-full">
<dt className="inline-flex items-center gap-2">
<Copy
text={sanitizeName(x.name.replace("text-", ""))}
copyText={x.name}
/>
</dt>
<dd className="text-text-subtle text-medium mt-auto">
{ref ? (
<Link
href={`#${ref.name}`}
className="focus-visible:bg-border-focus focus-visible:text-text-on-action hover:underline focus:outline-none"
>
{sanitizeName(ref.name)}
</Link>
) : (
getColorString(x.value)
)}
</dd>
</dl>
</div>
);
}}
/>
})}
</Grid>
);
}
return <Frame tokens={colors} styles="background" showHex />;
if (cat.startsWith("semantic-icon")) {
return (
<Grid>
{colors.map((x) => {
const ref = getGlobalReference(x.value);
const c = color(x.value);
const isLight = c.getLuminance() > 0.9;
return (
<div key={x.name} id={x.name} className="flex w-fit items-center">
<div
style={{
background: isLight ? `var(--a-surface-inverted)` : undefined,
boxShadow: `inset 0 2px 4px 0 rgba(0,0,0,0.06)`,
}}
className="mr-3 grid h-16 w-16 place-content-center rounded-lg text-4xl leading-none"
>
<PersonCircleIcon
aria-hidden
style={{
color: x.value,
}}
/>
</div>
<dl className="grid h-full">
<dt className="inline-flex items-center gap-2">
<Copy
text={sanitizeName(x.name.replace("icon-", ""))}
copyText={x.name}
/>
</dt>
<dd className="text-text-subtle text-medium mt-auto">
{ref ? (
<Link
href={`#${ref.name}`}
className="focus-visible:bg-border-focus focus-visible:text-text-on-action hover:underline focus:outline-none"
>
{sanitizeName(ref.name)}
</Link>
) : (
getColorString(x.value)
)}
</dd>
</dl>
</div>
);
})}
</Grid>
);
}
if (cat.startsWith("semantic-border")) {
return (
<Grid>
{colors.map((x) => {
const ref = getGlobalReference(x.value);
return (
<div key={x.name} id={x.name} className="flex w-fit items-center">
<div
style={{
boxShadow: `inset 0 0 0 3px var(${x.name})`,
}}
className="mr-3 grid h-16 w-16 place-content-center rounded-lg text-4xl leading-none"
/>
<dl className="grid h-full">
<dt className="inline-flex items-center gap-2">
<Copy
text={sanitizeName(x.name.replace("border-", ""))}
copyText={x.name}
/>
</dt>
<dd className="text-text-subtle text-medium mt-auto">
{ref ? (
<Link
href={`#${ref.name}`}
className="focus-visible:bg-border-focus focus-visible:text-text-on-action hover:underline focus:outline-none"
>
{sanitizeName(ref.name)}
</Link>
) : (
getColorString(x.value)
)}
</dd>
</dl>
</div>
);
})}
</Grid>
);
}
if (cat.startsWith("semantic-data-border")) {
return (
<Grid>
{colors.map((x) => {
const ref = getGlobalReference(x.value);
return (
<div
key={x.name}
id={x.name}
className="z-0 flex w-fit items-center"
>
<div className="mr-3 flex h-16 w-16 items-end justify-evenly rounded-lg text-4xl leading-none">
<span
className="rounded-t-small h-full w-3"
style={{
border: `1px solid var(${x.name})`,
backgroundColor: `var(${x.name.replace(
"border",
"surface"
)}-subtle)`,
}}
/>
<span
className="rounded-t-small h-2/3 w-3"
style={{
border: `1px solid var(${x.name})`,
backgroundColor: `var(${x.name.replace(
"border",
"surface"
)}-subtle)`,
}}
/>
<span
className="rounded-t-small h-1/3 w-3"
style={{
border: `1px solid var(${x.name})`,
backgroundColor: `var(${x.name.replace(
"border",
"surface"
)}-subtle)`,
}}
/>
</div>
<dl className="grid h-full">
<dt className="inline-flex items-center gap-2">
<Copy
text={sanitizeName(x.name.replace("surface-", ""))}
copyText={x.name}
/>
</dt>
<dd className="text-text-subtle text-medium mt-auto">
{ref ? (
<Link
href={`#${ref.name}`}
className="focus-visible:bg-border-focus focus-visible:text-text-on-action hover:underline focus:outline-none"
>
{sanitizeName(ref.name)}
</Link>
) : (
getColorString(x.value)
)}
</dd>
</dl>
</div>
);
})}
</Grid>
);
}
if (cat.startsWith("semantic-data-surface")) {
return (
<Grid>
{colors.map((x) => {
const ref = getGlobalReference(x.value);
return (
<div
key={x.name}
id={x.name}
className="z-0 flex w-fit items-center"
>
<div className="mr-3 flex h-16 w-16 items-end justify-evenly rounded-lg text-4xl leading-none">
<span
className="rounded-t-small h-full w-3"
style={{ backgroundColor: `var(${x.name})` }}
/>
<span
className="rounded-t-small h-2/3 w-3"
style={{ backgroundColor: `var(${x.name})` }}
/>
<span
className="rounded-t-small h-1/3 w-3"
style={{ backgroundColor: `var(${x.name})` }}
/>
</div>
<dl className="grid h-full">
<dt className="inline-flex items-center gap-2">
<Copy
text={sanitizeName(x.name.replace("surface-", ""))}
copyText={x.name}
/>
</dt>
<dd className="text-text-subtle text-medium mt-auto">
{ref ? (
<Link
href={`#${ref.name}`}
className="focus-visible:bg-border-focus focus-visible:text-text-on-action hover:underline focus:outline-none"
>
{sanitizeName(ref.name)}
</Link>
) : (
getColorString(x.value)
)}
</dd>
</dl>
</div>
);
})}
</Grid>
);
}
return (
<Grid>
{colors.map((x) => {
const ref = getGlobalReference(x.value);
return (
<div key={x.name} id={x.name} className="z-0 flex w-fit items-center">
<div
style={{
background: `var(${x.name})`,
boxShadow: `inset 0 2px 4px 0 rgba(0,0,0,0.06)`,
}}
className="mr-3 grid h-16 w-16 place-content-center rounded-lg text-4xl leading-none"
>
<div className="component-checkered-bg z-[-1] h-16 w-16" />
</div>
<dl className="grid h-full">
<dt className="inline-flex items-center gap-2">
<Copy
text={sanitizeName(x.name.replace("surface-", ""))}
copyText={x.name}
/>
</dt>
<dd className="text-text-subtle text-medium mt-auto">
{ref ? (
<Link
href={`#${ref.name}`}
className="focus-visible:bg-border-focus focus-visible:text-text-on-action hover:underline focus:outline-none"
>
{sanitizeName(ref.name)}
</Link>
) : (
getColorString(x.value)
)}
</dd>
</dl>
</div>
);
})}
</Grid>
);
};
@@ -1,38 +1,36 @@
import docs from "@navikt/ds-tokens/docs.json";
import { Frame } from "../Frame";
import { Copy } from "../Copy";
import { Grid } from "../Grid";
import { sanitizeName } from "../utilities";
export const ShadowView = ({ cat }: { cat: string }) => {
const shadows = docs[cat];
return (
<Frame
tokens={shadows}
styles="boxShadow"
element={({ token, name }: { token: string; name?: string }) => {
const isLigth = name && name.includes("focus-inverted");
<Grid stacked>
{shadows.map((x) => {
return (
<div
className="min-h-16 flex h-full w-full items-center justify-center rounded-md px-4 text-5xl font-semibold"
aria-hidden
style={{
background: isLigth
? `var(--a-surface-inverted)`
: `var(--a-surface-default)`,
}}
>
<div key={x.name} id={x.name} className="flex w-fit items-center">
<div
className="h-8 w-full rounded-md"
style={{
boxShadow: `${token}`,
background: isLigth
? "var(--a-surface-inverted)"
: "var(--a-bg-subtle)",
boxShadow: `var(${x.name})`,
}}
className="mr-3 grid h-16 w-16 place-content-center rounded-lg text-4xl leading-none"
/>
<dl className="grid h-full">
<dt className="inline-flex items-center gap-2">
<Copy
text={sanitizeName(x.name.replace("shadow-", ""))}
copyText={x.name}
/>
</dt>
<dd className="text-text-subtle text-medium mt-auto">
{x.value}
</dd>
</dl>
</div>
);
}}
/>
})}
</Grid>
);
};
@@ -1,37 +1,34 @@
import docs from "@navikt/ds-tokens/docs.json";
import { Frame } from "../Frame";
import { Copy } from "../Copy";
import { Grid } from "../Grid";
import { sanitizeName } from "../utilities";
export const ShapesView = ({ cat }: { cat: string }) => {
const shapes = docs[cat];
return (
<Frame
tokens={shapes}
styles="borderRadius"
element={({ token }: { token: string; name?: string }) => {
<Grid>
{shapes.map((x) => {
return (
<div
className="min-h-16 flex h-full w-full items-center justify-center gap-4 rounded-md px-4 text-5xl font-semibold"
aria-hidden
style={{
background: `var(--a-surface-default)`,
}}
>
<div key={x.name} id={x.name} className="flex w-fit items-center">
<div
className="bg-surface-alt-3-strong h-8 w-8 rounded-md"
style={{
borderRadius: `${token}`,
}}
/>
<div
className="bg-surface-alt-3-strong h-8 w-20 rounded-md"
style={{
borderRadius: `${token}`,
}}
style={{ borderRadius: x.value }}
className="bg-surface-alt-3-strong mr-3 grid h-16 w-16 place-content-center rounded-lg text-4xl leading-none"
/>
<dl className="grid h-full">
<dt className="inline-flex items-center gap-2">
<Copy
text={sanitizeName(x.name.replace("border-radius-", ""))}
copyText={x.name}
/>
</dt>
<dd className="text-text-subtle text-medium mt-auto">
{x.value}
</dd>
</dl>
</div>
);
}}
/>
})}
</Grid>
);
};
@@ -1,31 +1,41 @@
import docs from "@navikt/ds-tokens/docs.json";
import { Frame } from "../Frame";
import { AkselTable, AkselTableRow } from "components/website-modules/Table";
export const SpacingView = ({ cat }: { cat: string }) => {
const spacings = docs[cat];
return (
<Frame
tokens={spacings}
styles="boxShadow"
element={({ token }: { token: string; name?: string }) => {
return (
<div
className="min-h-16 flex h-full w-full items-center justify-start rounded-md px-4 text-5xl font-semibold"
aria-hidden
style={{
background: `var(--a-surface-default)`,
}}
>
<div
className="bg-surface-alt-3-strong h-8 rounded-md"
style={{
width: token,
}}
/>
</div>
);
}}
/>
<AkselTable
withCopy
th={[
{ text: "Token" },
{ text: "rem" },
{ text: "px" },
{ text: "demo", sronly: true, hideOnSm: true },
]}
>
{spacings.map((x) => (
<AkselTableRow
key={x.name}
tr={[
{ text: x.name.replace("--a-spacing-", "") },
{ text: x.value.replace("rem", "") },
{ text: Number(x.value.replace("rem", "") * 16) },
{
hideOnSm: true,
text: (
<div
className="bg-surface-alt-3-strong mr-auto h-8 rounded-md"
style={{
width: x.value,
}}
/>
),
},
]}
copyText={x.name}
/>
))}
</AkselTable>
);
};
@@ -1,26 +1,49 @@
import docs from "@navikt/ds-tokens/docs.json";
import { Frame } from "../Frame";
import cl from "clsx";
import { Copy } from "../Copy";
import { Grid } from "../Grid";
import { sanitizeName } from "../utilities";
export const ZindexView = ({ cat }: { cat: string }) => {
const shapes = docs[cat];
const zindex = docs[cat];
return (
<Frame
tokens={shapes}
styles="borderRadius"
element={({ token }: { token: string; name?: string }) => {
<Grid>
{zindex.map((x, y) => {
return (
<div
className="min-h-16 flex h-full w-full items-end rounded-md px-4 text-5xl font-semibold"
aria-hidden
style={{
background: `var(--a-surface-default)`,
}}
>
{token}
<div key={x.name} id={x.name} className="flex w-fit items-center">
<div
style={{ boxShadow: `inset 0 2px 4px 0 rgba(0,0,0,0.06)` }}
className="bg-surface-subtle mr-3 flex h-16 w-16 flex-col-reverse justify-between overflow-hidden rounded-lg text-4xl leading-none"
>
{zindex.map((x, xi) => (
<div
aria-hidden
key={x.value}
className={cl(
"h-3 w-16 group-hover:opacity-10 peer-focus-visible:opacity-10",
{
"bg-surface-alt-3-strong": y === xi,
"bg-surface-neutral-subtle": y !== xi,
}
)}
/>
))}
</div>
<dl className="grid h-full">
<dt className="inline-flex items-center gap-2">
<Copy
text={sanitizeName(x.name.replace("z-index-", ""))}
copyText={x.name}
/>
</dt>
<dd className="text-text-subtle text-medium mt-auto">
{x.value}
</dd>
</dl>
</div>
);
}}
/>
})}
</Grid>
);
};
@@ -1,5 +1,5 @@
import { withErrorBoundary } from "@/error-boundary";
import { BreakpointsView } from "components/sanity-modules/token-view/categories/Breakpoints";
import { BreakpointsView } from "./categories/Breakpoints";
import { FontView } from "./categories/Font";
import { GlobalView } from "./categories/Global";
import { SemanticView } from "./categories/Semantic";
@@ -0,0 +1,37 @@
import { FontView } from "./categories/Font";
import { GlobalView } from "./categories/Global";
import { SemanticView } from "./categories/Semantic";
import { ShadowView } from "./categories/Shadow";
import { SpacingView } from "./categories/Spacing";
import { ZindexView } from "./categories/Zindex";
import { BreakpointsView } from "./categories/Breakpoints";
import { ShapesView } from "./categories/Shapes";
import "../../../dist/tw.css";
export default {
title: "sanity-modules/tokenview",
parameters: {
layout: "fullscreen",
},
};
export const FontViewDemo = () => <FontView cat="font" />;
export const GlobalViewDemo = () => <GlobalView cat="global-blue" />;
export const SemanticViewDemo = () => <SemanticView cat="semantic-surface" />;
export const SemanticBorderView = () => <SemanticView cat="semantic-border" />;
export const SemanticIconView = () => <SemanticView cat="semantic-icon" />;
export const SemanticTextView = () => <SemanticView cat="semantic-text" />;
export const RadiusViewDemo = () => <ShapesView cat="radius" />;
export const ShadowViewDemo = () => <ShadowView cat="shadow" />;
export const SpacingViewDemo = () => <SpacingView cat="spacing" />;
export const IndexView = () => <ZindexView cat="z-index" />;
export const BreakpointView = () => <BreakpointsView cat="breakpoints" />;
@@ -0,0 +1,24 @@
import color from "tinycolor2";
import docs from "@navikt/ds-tokens/docs.json";
const capitalize = (s: string) => s.charAt(0).toUpperCase() + s.slice(1);
export const sanitizeName = (x: string) =>
capitalize(x.replace("--a-", "").replaceAll("-", " "));
export const getColorString = (s: string) => {
const c = color(s);
const alpha = c.getAlpha() !== 1;
return alpha ? c.toRgbString() : c.toHexString().toUpperCase();
};
export const getGlobalReference = (
semanticValue: string
): { name: string; value: string } => {
const globalRefs = Object.entries(docs)
.filter(([key]) => key.startsWith("global-"))
.reduce((acc, [_, value]) => [...acc, ...value], []);
return globalRefs.find(({ value }) => semanticValue === value) ?? null;
};
@@ -0,0 +1,7 @@
export const InlineCode = (props: React.HTMLAttributes<HTMLElement>) => (
<code className="text-deepblue-800 font-mono text-sm font-semibold leading-normal before:contents">
<span aria-hidden>`</span>
<span>{props.children}</span>
<span aria-hidden>`</span>
</code>
);
@@ -0,0 +1,17 @@
import cl from "clsx";
export const KBD = (props: React.HTMLAttributes<HTMLElement>) => (
<kbd
className={cl(
"mx-05 ring-border-subtle my-0 inline-block min-w-[2rem] rounded-md px-2 py-[1px] text-center font-mono text-sm text-gray-900 ring-1 ring-inset",
"from-surface-default via-surface-default to-surface-neutral-subtle bg-gradient-to-b"
)}
>
<span className="kbd">{props.children}</span>
<style jsx>{`
.kbd {
text-shadow: 0 1px 0px var(--a-grayalpha-200);
}
`}</style>
</kbd>
);
@@ -0,0 +1,74 @@
import { CopyButton } from "@navikt/ds-react";
import cl from "clsx";
import { createContext, useContext } from "react";
const TableContext = createContext<boolean>(false);
export function AkselTable({
children,
th,
withCopy,
}: {
children: React.ReactNode;
th: { text: string; hideOnSm?: boolean; sronly?: boolean }[];
withCopy?: boolean;
}) {
return (
<table className="border-border-subtle mb-7 w-full border-separate border-spacing-0 rounded border">
<thead>
<tr className="rounded-t text-left">
{th.map((x) => (
<th
key={x.text}
className={cl("font-regular bg-surface-subtle rounded-tl p-2", {
"hidden sm:table-cell": !!x.hideOnSm,
})}
>
{x?.sronly ? <span className="sr-only">{x.text}</span> : x.text}
</th>
))}
{withCopy && (
<th className="font-regular bg-surface-subtle hidden rounded-tl p-2 sm:table-cell">
<span className="sr-only">Kopi</span>
</th>
)}
</tr>
</thead>
<tbody>
<TableContext.Provider value={withCopy ?? false}>
{children}
</TableContext.Provider>
</tbody>
</table>
);
}
export function AkselTableRow({
tr,
copyText = "",
}: {
tr: { text: string | React.ReactNode; hideOnSm?: boolean }[];
copyText?: string;
}) {
const useCopy = useContext(TableContext);
return (
<tr className="peer border-b border-t border-gray-200 text-base last-of-type:rounded-b">
{tr.map((x, xi) => (
<td
key={xi}
className={cl("border-t border-gray-200 px-2 py-1", {
"hidden sm:table-cell": !!x.hideOnSm,
})}
>
{x.text}
</td>
))}
{useCopy && (
<td className="hidden border-t border-gray-200 px-2 py-1 sm:table-cell">
<CopyButton copyText={copyText} size="small" className="ml-auto" />
</td>
)}
</tr>
);
}
@@ -1,41 +0,0 @@
import { SuggestionBlock } from "./index";
import { Meta } from "@storybook/react";
import { NextDecorator } from "../../StoryDecorator";
const MetaData: Meta = {
component: SuggestionBlock,
tags: ["autodocs"],
decorators: [
(Story) => (
<NextDecorator>
<Story />
</NextDecorator>
),
],
};
export default MetaData;
export const Ikoner = {
render: () => <SuggestionBlock variant="ikoner" />,
};
export const Ikon = {
render: () => <SuggestionBlock variant="ikon" />,
};
export const Komponent = {
render: () => <SuggestionBlock variant="komponent" />,
};
export const KomponentBeta = {
render: () => <SuggestionBlock variant="komponent-beta" />,
};
export const KomponentNy = {
render: () => <SuggestionBlock variant="komponent-ny" />,
};
export const Komponenter = {
render: () => <SuggestionBlock variant="komponenter" />,
};
+7
View File
@@ -0,0 +1,7 @@
import pino from "pino";
import { logger as sharedPinoConfig } from "./next-logger.config";
/**
* This logger is not isomorphic, and should only be used on the server
*/
export const logger: pino.Logger = sharedPinoConfig();
@@ -0,0 +1,32 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const pino = require("pino");
const logger = (defaultConfig = {}) =>
pino({
...defaultConfig,
timestamp: false,
formatters: {
level: (label) => {
return { level: label };
},
log: (object) => {
if (object.err) {
// massage the error object so logs.adeo.no shows stack traces
const err =
object.err instanceof Error
? pino.stdSerializers.err(object.err)
: object.err;
object.stack_trace = err.stack;
object.type = err.type;
object.message = err.message;
delete object.err;
}
return object;
},
},
});
module.exports = {
logger,
};
+7 -5
View File
@@ -5,7 +5,7 @@
"description": "Aksel.nav.no website",
"author": "Aksel | NAV designsystem team",
"scripts": {
"dev": "next",
"dev": "next | pino-pretty",
"build:old": "next build",
"build": "next build && yarn cp:assets",
"start": "cd .next/standalone/aksel.nav.no/website && node server.js",
@@ -34,19 +34,20 @@
"@sanity/image-url": "1.0.2",
"@sanity/preview-kit": "^1.5.4",
"@sanity/table": "1.0.1",
"@sanity/ui": "^1.3.3",
"@sanity/vision": "3.11.5",
"@sanity/ui": "^1.5.0",
"@sanity/vision": "3.12.0",
"@svgr/webpack": "^5.5.0",
"amplitude-js": "^8.21.5",
"boring-avatars": "1.7.0",
"clsx": "^1.2.1",
"codesandbox": "^2.2.3",
"copy-to-clipboard": "^3.3.1",
"date-fns": "2.29.3",
"fuse.js": "^6.6.2",
"lodash": "^4.17.21",
"next": "^13.2.1",
"next-logger": "^3.0.2",
"next-sanity": "^4.3.3",
"pino": "^8.14.1",
"prism-react-renderer": "^1.3.0",
"prismjs": "^1.27.0",
"react": "^18.0.0",
@@ -54,7 +55,7 @@
"react-modal": "3.15.1",
"react-responsive-masonry": "^2.1.7",
"recharts": "^2.2.0",
"sanity": "3.11.5",
"sanity": "3.12.0",
"sanity-plugin-asset-source-unsplash": "^1.1.0",
"sanity-plugin-media": "^2.0.5",
"sharp": "0.31.3",
@@ -82,6 +83,7 @@
"jest": "^29.0.0",
"jest-environment-jsdom": "^29.0.0",
"json5": "2.2.1",
"pino-pretty": "^10.0.0",
"postcss": "^8.4.0",
"postcss-import": "^14.1.0",
"postcss-loader": "7.0.0",
+3
View File
@@ -1,3 +1,6 @@
// This is imported to allow the Output File Tracing feature of Next.js to work correctly with the log patcher
import "next-logger";
import { Html, Head, Main, NextScript } from "next/document";
export default function Document() {
+5 -4
View File
@@ -1,6 +1,7 @@
import { noCdnClient } from "@/sanity/client.server";
import { FeedbackT } from "@/types";
import dotenv from "dotenv";
import { logger } from "logger";
import type { NextApiRequest, NextApiResponse } from "next";
dotenv.config();
@@ -28,7 +29,7 @@ export default async function handler(
const token = process.env.SANITY_WRITE_KEY;
if (!token && isDevelopment) {
console.log("No token! api/feedback");
logger.info("No token! api/feedback");
return;
}
@@ -61,12 +62,12 @@ export default async function handler(
await transactionClient
.commit()
.then(() => console.log("Feedback-logged"))
.catch((e) => console.error(e.message));
.then(() => logger.info("Feedback-logged"))
.catch((e) => logger.error(e.message));
return res.json({ status: "ok" });
} catch (err) {
console.error(err);
logger.error(err);
res.status(500).json({ msg: "Error, check console" });
}
break;
@@ -1,5 +1,6 @@
import { noCdnClient } from "@/sanity/client.server";
import { format, isSameWeek } from "date-fns";
import { logger } from "logger";
import { NextApiRequest, NextApiResponse } from "next";
const token = process.env.SANITY_WRITE_KEY;
@@ -63,7 +64,7 @@ export default async function logPageView(
.inc({ pageviews: 1 })
.commit()
.catch((err) => {
console.error("Error:", err);
logger.error(err);
return res.status(500).json({ message: "Error updating page" });
});
@@ -78,7 +79,7 @@ export default async function logPageView(
.inc({ "weeksObj.weeks[0].views": 1 })
.commit()
.catch((err) => {
console.error("Error:", err);
logger.error(err);
return res.status(500).json({ message: "Error updating current week" });
});
} else {
@@ -97,7 +98,7 @@ export default async function logPageView(
autoGenerateArrayKeys: true,
})
.catch((err) => {
console.error("Error:", err);
logger.error(err);
return res.status(500).json({ message: "Error creating new week" });
});
}
+2 -1
View File
@@ -1,4 +1,5 @@
import { noCdnClient } from "@/sanity/client.server";
import { logger } from "logger";
import { NextApiRequest, NextApiResponse } from "next";
const token = process.env.SANITY_WRITE_KEY;
@@ -60,7 +61,7 @@ export default async function logPageScroll(
})
.commit()
.catch((err) => {
console.error("Error:", err);
logger.error(err);
return res.status(500).json({ message: "Error updating metrics" });
});
+2 -1
View File
@@ -1,6 +1,7 @@
import { noCdnClient } from "@/sanity/client.server";
import { NextApiRequest, NextApiResponse } from "next";
import { calcNewAverage } from "./log-scroll";
import { logger } from "logger";
const token = process.env.SANITY_WRITE_KEY;
@@ -47,7 +48,7 @@ export default async function logTime(
})
.commit()
.catch((err) => {
console.error("Error:", err);
logger.error(err);
return res.status(500).json({ message: "Error updating page" });
});
@@ -11,6 +11,7 @@ import Fuse from "fuse.js";
import { NextApiRequest, NextApiResponse } from "next";
import { allArticleDocuments } from "../../../../sanity/config";
import IconMetadata from "@navikt/aksel-icons/metadata";
import { logger } from "logger";
const token = process.env.SANITY_PRIVATE_NO_DRAFTS;
@@ -225,7 +226,7 @@ async function searchSanity() {
);
})
.catch((err) => {
console.log("Error message: ", err.message);
logger.error(err);
return [];
});
+1 -1
View File
@@ -1,7 +1,7 @@
import { InlineCode } from "@/sanity-block";
import { ExternalLinkIcon } from "@navikt/aksel-icons";
import { BodyLong, Heading, Link } from "@navikt/ds-react";
import { KBD } from "@sanity/ui";
import { InlineCode } from "components/website-modules/InlineCode";
import NextLink from "next/link";
import { Role } from "sanity";
+2 -2
View File
@@ -10,8 +10,8 @@
"preview": "vite preview"
},
"dependencies": {
"@navikt/ds-css": "4.1.2",
"@navikt/ds-react": "4.1.2",
"@navikt/ds-css": "4.1.6",
"@navikt/ds-react": "4.1.6",
"react": "^18.0.0",
"react-dom": "^18.0.0"
},
+1726 -1344
View File
File diff suppressed because it is too large. Load diff