mirror of
https://github.com/navikt/aksel.git
synced 2026-10-13 09:12:03 +00:00
Compare commits
19
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
659e835da9 | ||
|
|
e10f4375b1 | ||
|
|
9a8bb26c36 | ||
|
|
69aea38784 | ||
|
|
8f16d1571e | ||
|
|
e2265c9a78 | ||
|
|
925aa7a140 | ||
|
|
7c17e40cac | ||
|
|
3c8889ea88 | ||
|
|
e060961050 | ||
|
|
18aa4ee7fb | ||
|
|
f44edd76a2 | ||
|
|
1fa636bdd5 | ||
|
|
44a75acb6b | ||
|
|
550faee900 | ||
|
|
88b6174b0b | ||
|
|
fbf016b3bd | ||
|
|
09fa503b98 | ||
|
|
f5688485f5 |
No files matched your search
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -7,5 +7,5 @@ keywords:
|
||||
- delete
|
||||
- slett
|
||||
variant: Stroke
|
||||
updated_at: 08.03.2023
|
||||
updated_at: 24.05.2023
|
||||
created_at: 07.03.2023
|
||||
@@ -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,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": {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)}
|
||||
|
||||
@@ -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(() => {
|
||||
|
||||
@@ -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>;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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": [
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
+41
-105
@@ -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>
|
||||
);
|
||||
};
|
||||
+293
-81
@@ -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>
|
||||
);
|
||||
}
|
||||
-41
@@ -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" />,
|
||||
};
|
||||
@@ -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,
|
||||
};
|
||||
@@ -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",
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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" });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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" });
|
||||
});
|
||||
|
||||
|
||||
@@ -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,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";
|
||||
|
||||
|
||||
@@ -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"
|
||||
},
|
||||
|
||||
Reference in new issue
Block a user