@leabankab/component-library 8.6.0 → 8.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/dist/component-library.es.js +1925 -1087
  3. package/dist/component-library.es.js.map +1 -1
  4. package/dist/component-library.umd.js +2 -2
  5. package/dist/component-library.umd.js.map +1 -1
  6. package/dist/components/buttons/action-button.d.ts +34 -4
  7. package/dist/components/buttons/button-base.d.ts +5 -2
  8. package/dist/components/buttons/icon-button.d.ts +16 -2
  9. package/dist/components/color-roles.d.ts +7 -1
  10. package/dist/components/data-display/arrow-circle.d.ts +21 -0
  11. package/dist/components/data-display/article-card.d.ts +88 -0
  12. package/dist/components/data-display/avatar.d.ts +33 -0
  13. package/dist/components/data-display/chip.d.ts +8 -3
  14. package/dist/components/data-display/featured-image.d.ts +42 -0
  15. package/dist/components/data-display/index.d.ts +12 -0
  16. package/dist/components/data-display/link-card.d.ts +52 -0
  17. package/dist/components/data-display/media-card.d.ts +102 -0
  18. package/dist/components/data-display/partner-row.d.ts +46 -0
  19. package/dist/components/data-display/rich-text.d.ts +27 -0
  20. package/dist/components/data-display/service-card.d.ts +80 -0
  21. package/dist/components/data-display/star-rating.d.ts +26 -0
  22. package/dist/components/data-display/table.d.ts +93 -0
  23. package/dist/components/data-display/testimonial-card.d.ts +43 -0
  24. package/dist/components/data-display/use-star-rating-labels.d.ts +5 -0
  25. package/dist/components/data-display/use-video-player-labels.d.ts +2 -0
  26. package/dist/components/data-display/video-player.d.ts +22 -0
  27. package/dist/components/data-display/website-card.d.ts +10 -0
  28. package/dist/components/feedback/index.d.ts +1 -0
  29. package/dist/components/feedback/skeleton.d.ts +22 -0
  30. package/dist/components/navigation/breadcrumbs.d.ts +38 -0
  31. package/dist/components/navigation/index.d.ts +3 -0
  32. package/dist/components/navigation/pagination-dots.d.ts +34 -0
  33. package/dist/components/navigation/pagination.d.ts +37 -0
  34. package/dist/components/navigation/use-breadcrumbs-labels.d.ts +2 -0
  35. package/dist/components/navigation/use-pagination-labels.d.ts +7 -0
  36. package/dist/components/surfaces/accordion.d.ts +5 -1
  37. package/dist/components/surfaces/index.d.ts +1 -0
  38. package/dist/components/surfaces/panel.d.ts +30 -0
  39. package/dist/components/typography/link.d.ts +14 -1
  40. package/dist/cookie-consent-react.cjs +1 -1
  41. package/dist/cookie-consent-react.cjs.map +1 -1
  42. package/dist/cookie-consent-react.mjs +22 -22
  43. package/dist/cookie-consent-react.mjs.map +1 -1
  44. package/dist/cookie-consent.css +1 -1
  45. package/dist/date-picker.cjs +1 -1
  46. package/dist/date-picker.cjs.map +1 -1
  47. package/dist/date-picker.mjs +216 -203
  48. package/dist/date-picker.mjs.map +1 -1
  49. package/dist/index.css +1 -1
  50. package/dist/index.d.ts +1 -1
  51. package/dist/tailwind.css +16 -0
  52. package/dist/theme/index.d.ts +1 -1
  53. package/dist/theme/token-types.d.ts +13 -3
  54. package/dist/theme/tokens/breakpoints.d.ts +20 -0
  55. package/dist/theme/tokens/font-family.d.ts +6 -0
  56. package/dist/theme/tokens/index.d.ts +1 -0
  57. package/dist/theme/tokens/shadows.d.ts +6 -0
  58. package/dist/theme/tokens/text-styles.d.ts +8 -0
  59. package/dist/theme/tokens/widths.d.ts +10 -0
  60. package/dist/theme/types.d.ts +9 -1
  61. package/package.json +1 -1
@@ -1,16 +1,46 @@
1
+ import { ReactNode } from 'react';
1
2
  import { ButtonRootProps } from './button-base';
2
- export type ActionButtonProps = Omit<ButtonRootProps, "loading">;
3
+ export type ActionButtonSize = "sm" | "lg";
4
+ /**
5
+ * With `iconOnly` the label is hidden but stays the accessible name, so it is
6
+ * required there.
7
+ */
8
+ type ActionButtonLabel = {
9
+ /**
10
+ * Shows only the arrow: a round button, with the label kept for screen
11
+ * readers. Used where space is short, such as a collapsed
12
+ * `ExpandingCards` item.
13
+ * @default false
14
+ */
15
+ iconOnly?: false;
16
+ children?: ReactNode;
17
+ } | {
18
+ iconOnly: true;
19
+ children: ReactNode;
20
+ };
21
+ export type ActionButtonProps = Omit<ButtonRootProps, "loading" | "children"> & ActionButtonLabel & {
22
+ /**
23
+ * `"lg"` is 56px tall with a 48px arrow; `"sm"` is 40px tall with a 32px
24
+ * arrow, for headers and tight rows.
25
+ * @default "lg"
26
+ */
27
+ size?: ActionButtonSize;
28
+ };
3
29
  /**
4
30
  * A pill-shaped call-to-action button with a built-in arrow icon.
5
31
  *
6
32
  * Used for primary navigation actions on the website, such as hero sections
7
- * and landing pages. To render a link, pass it through `render`; an element
8
- * with `href` or `to` is rendered as a real link, without button semantics:
33
+ * and landing pages. On hover the label slides towards the arrow and the arrow
34
+ * turns purple and points up and to the right. To render a link, pass it
35
+ * through `render`; an element with `href` or `to` is rendered as a real link,
36
+ * without button semantics:
9
37
  *
10
38
  * ```tsx
11
39
  * <ActionButton render={<a href="/lan" />}>Se våra lån</ActionButton>
12
40
  * <ActionButton render={<NextLink href="/lan" />}>Se våra lån</ActionButton>
13
41
  * <ActionButton render={<RouterLink to="/lan" />}>Se våra lån</ActionButton>
42
+ * <ActionButton size="sm" iconOnly render={<a href="/lan" />}>Se våra lån</ActionButton>
14
43
  * ```
15
44
  */
16
- export declare function ActionButton({ children, className, ...rest }: ActionButtonProps): import("react").JSX.Element;
45
+ export declare function ActionButton({ children, className, size, iconOnly, ...rest }: ActionButtonProps): import("react").JSX.Element;
46
+ export {};
@@ -43,6 +43,9 @@ export declare function ButtonRoot({ loading, disabled, className, render, nativ
43
43
  /**
44
44
  * The root shared by `Button`, `IconButton`, `CloseButton` and
45
45
  * `DownloadTrigger`: `ButtonRoot` with the button look. Internal — not
46
- * exported from the package.
46
+ * exported from the package. It also takes `"elevated"`, which only
47
+ * `IconButton` offers.
47
48
  */
48
- export declare function ButtonBase({ variant, color, size, className, ...rest }: ButtonBaseProps): import("react").JSX.Element;
49
+ export declare function ButtonBase({ variant, color, size, className, ...rest }: Omit<ButtonBaseProps, "variant"> & {
50
+ variant?: ButtonVariant | "elevated";
51
+ }): import("react").JSX.Element;
@@ -1,5 +1,12 @@
1
1
  import { ReactNode } from 'react';
2
- import { ButtonBaseProps } from './button-base';
2
+ import { ButtonBaseProps, ButtonVariant } from './button-base';
3
+ /**
4
+ * The variants of `Button`, plus `"elevated"`: a white disc with the website's
5
+ * soft shadow, for controls that float over a picture or a coloured section
6
+ * (the arrows of a carousel, the play button of a video). At `md` it is 40px,
7
+ * the website's size; `sm` and `lg` match the other variants.
8
+ */
9
+ export type IconButtonVariant = ButtonVariant | "elevated";
3
10
  /**
4
11
  * Requires an accessible name so the button is never nameless. Provide exactly
5
12
  * one of `aria-label` or `aria-labelledby`.
@@ -11,9 +18,16 @@ type IconButtonAccessibleName = {
11
18
  "aria-labelledby": string;
12
19
  "aria-label"?: never;
13
20
  };
14
- export type IconButtonProps = Omit<ButtonBaseProps, "children" | "aria-label" | "aria-labelledby"> & IconButtonAccessibleName & {
21
+ export type IconButtonProps = Omit<ButtonBaseProps, "children" | "aria-label" | "aria-labelledby" | "variant"> & IconButtonAccessibleName & {
15
22
  /** The icon. Mark it `aria-hidden` — the name comes from `aria-label`. */
16
23
  children: ReactNode;
24
+ /**
25
+ * Visual weight: `"solid"`, `"outline"` and `"ghost"` as on `Button`, or
26
+ * `"elevated"`, a white disc with the website's soft shadow
27
+ * (`shadow-soft`) and the icon in `color`; 40px at `md`.
28
+ * @default "solid"
29
+ */
30
+ variant?: IconButtonVariant;
17
31
  };
18
32
  /**
19
33
  * A square, icon-only button with the same variants, colours and sizes as
@@ -1,4 +1,4 @@
1
- import { ColorRole } from '../theme/token-types';
1
+ import { ColorRole, SurfaceRole } from '../theme/token-types';
2
2
  /**
3
3
  * A component's own subset of `ColorRole`:
4
4
  * `ColorRoles<"primary" | "secondary" | "error">`. A name outside the shared
@@ -6,3 +6,9 @@ import { ColorRole } from '../theme/token-types';
6
6
  * not exported from the package.
7
7
  */
8
8
  export type ColorRoles<Role extends ColorRole> = Role;
9
+ /**
10
+ * A website component's own subset of `SurfaceRole`, for its `surface` prop,
11
+ * written to the root as `data-surface`: `SurfaceRoles<"base" | "muted">`.
12
+ * Internal: not exported from the package.
13
+ */
14
+ export type SurfaceRoles<Role extends SurfaceRole> = Role;
@@ -0,0 +1,21 @@
1
+ export type ArrowCircleProps = {
2
+ /**
3
+ * `"outline"`: a 2px ring and the arrow in the text colour, as on a
4
+ * `LinkCard`. `"filled"`: a near-black disc with a white arrow, the arrow of
5
+ * the website's call-to-action button.
6
+ * @default "outline"
7
+ */
8
+ variant?: "outline" | "filled";
9
+ /**
10
+ * `"lg"` is 48px with a 24px arrow, `"sm"` 32px with a 20px arrow.
11
+ * @default "lg"
12
+ */
13
+ size?: "sm" | "lg";
14
+ className?: string;
15
+ };
16
+ /**
17
+ * The round arrow of the website's cards (Figma `.ArrowCircle`). Decoration:
18
+ * hidden from screen readers, and the card it sits in moves it on hover.
19
+ * Internal: not exported from the package.
20
+ */
21
+ export declare function ArrowCircle({ variant, size, className, }: ArrowCircleProps): import("react").JSX.Element;
@@ -0,0 +1,88 @@
1
+ import { useRender } from '@base-ui/react/use-render';
2
+ import { ReactElement, ReactNode, Ref } from 'react';
3
+ export type ArticleCardVariant = "post" | "job";
4
+ /** An article card always leads somewhere: an `href`, or a router link. */
5
+ type ArticleCardTarget = {
6
+ /** Where the card leads: the article or the job opening. */
7
+ href: string;
8
+ render?: never;
9
+ } | {
10
+ href?: never;
11
+ /**
12
+ * A router link to render instead of the `<a>`, carrying its own
13
+ * destination: `render={<NextLink href="/okonomiguiden/smalan" />}`.
14
+ */
15
+ render: ReactElement;
16
+ };
17
+ /** `alt` is required with a photo, `""` when it is decoration. */
18
+ type ArticleCardImage = {
19
+ /** The article's photo. Job openings have none. */
20
+ src: string;
21
+ /**
22
+ * What the photo shows, for screen readers; `""` when it is decoration
23
+ * and the title says it all.
24
+ */
25
+ alt: string;
26
+ /**
27
+ * The image element to render instead of the plain `<img>`, such as
28
+ * `next/image` with `fill`, or an `<img loading="lazy">`. Its own props
29
+ * win over `src` and `alt`.
30
+ */
31
+ imageRender?: ReactElement;
32
+ } | {
33
+ src?: undefined;
34
+ alt?: undefined;
35
+ imageRender?: undefined;
36
+ };
37
+ export type ArticleCardProps = Omit<useRender.ComponentProps<"a">, "ref" | "title" | "children" | "href" | "render"> & ArticleCardTarget & ArticleCardImage & {
38
+ /** The rendered element: the `<a>`, or the link passed to `render`. */
39
+ ref?: Ref<HTMLElement>;
40
+ /** The title of the article, which also names the link. */
41
+ title: ReactNode;
42
+ /**
43
+ * The element for the title, an `<h3>` by default, under the list's own
44
+ * heading: `titleRender={<h2 />}`.
45
+ */
46
+ titleRender?: ReactElement;
47
+ /** A short summary under the title, cut off after two lines. */
48
+ excerpt?: ReactNode;
49
+ /**
50
+ * The facts under the excerpt, each shown as a beige pill: the category
51
+ * and the date of a post, or the place, the employment type and the
52
+ * closing date of a job. Pass them formatted.
53
+ */
54
+ meta?: ReactNode[];
55
+ /**
56
+ * `"post"`: an article, with its photo beside the text (above it below
57
+ * 768px) and 64px corners. `"job"`: a job opening, text only, with 32px
58
+ * corners.
59
+ * @default "post"
60
+ */
61
+ variant?: ArticleCardVariant;
62
+ };
63
+ /**
64
+ * An item in the website's list of articles or of job openings: a white card
65
+ * that is one link, with the title, a two-line excerpt and the facts as
66
+ * pills. On hover the title is underlined.
67
+ *
68
+ * ```tsx
69
+ * <ul>
70
+ * <li>
71
+ * <ArticleCard
72
+ * render={<NextLink href="/okonomiguiden/smalan" />}
73
+ * title="Slik refinansierer du dyre smålån"
74
+ * excerpt="Har du flere smålån og kredittkort? …"
75
+ * meta={["Lån", "12. mars 2026"]}
76
+ * src="/bilder/smalan.jpg"
77
+ * alt=""
78
+ * />
79
+ * </li>
80
+ * </ul>
81
+ * ```
82
+ *
83
+ * The link is named by the title and described by the excerpt and the
84
+ * facts. Put the cards in a list of the page's own; they take the width they
85
+ * are given.
86
+ */
87
+ export declare function ArticleCard({ title, titleRender, excerpt, meta, src, alt, imageRender, variant, render, ref, className, ...rest }: ArticleCardProps): ReactElement<unknown, string | import('react').JSXElementConstructor<any>>;
88
+ export {};
@@ -0,0 +1,33 @@
1
+ import { Avatar as BaseAvatar } from '@base-ui/react/avatar';
2
+ import { ReactElement } from 'react';
3
+ export type AvatarProps = Omit<BaseAvatar.Root.Props, "children"> & {
4
+ /**
5
+ * The photo. Without one, while it loads and when it fails, the avatar is a
6
+ * grey disc.
7
+ */
8
+ src?: string;
9
+ /**
10
+ * What the photo shows, for screen readers. Use `""` when the person's name
11
+ * is written beside it, as in a testimonial, so it is not read twice.
12
+ */
13
+ alt: string;
14
+ /**
15
+ * The image element to render instead of an `<img>`, such as `next/image`:
16
+ * `imageRender={<NextImage src={photo} alt="" width={48} height={48} />}`.
17
+ * Pass the photo in `src` as well: the avatar loads it to know when to
18
+ * show the image.
19
+ */
20
+ imageRender?: ReactElement;
21
+ };
22
+ /**
23
+ * A round 48px photo of a person, on Base UI's `Avatar`: the photo when it has
24
+ * loaded, a grey disc until then or without one.
25
+ *
26
+ * ```tsx
27
+ * <Avatar src="/kunder/kari.jpg" alt="" />
28
+ * ```
29
+ *
30
+ * `alt` is required. With a name in it, the disc carries the name while
31
+ * there is no photo; with `""`, the avatar is hidden from screen readers.
32
+ */
33
+ export declare function Avatar({ src, alt, imageRender, className, ...rest }: AvatarProps): import("react").JSX.Element;
@@ -1,15 +1,16 @@
1
1
  import { ComponentProps, MouseEvent, ReactNode } from 'react';
2
2
  import { ColorRoles } from '../color-roles';
3
- export type ChipColor = ColorRoles<"primary" | "tertiary" | "neutral" | "success" | "info" | "warning" | "error">;
3
+ export type ChipColor = ColorRoles<"primary" | "tertiary" | "neutral" | "muted" | "success" | "info" | "warning" | "error">;
4
4
  export type ChipVariant = "filled" | "outlined";
5
- export type ChipSize = "sm" | "md";
5
+ export type ChipSize = "sm" | "md" | "lg";
6
6
  export type ChipProps = Omit<ComponentProps<"span">, "children" | "color"> & {
7
7
  /** The text of the chip. */
8
8
  label: ReactNode;
9
9
  /**
10
10
  * What the chip stands for.
11
11
  * - A tag without a status: `"primary"` (purple), `"tertiary"` (teal) or
12
- * `"neutral"` (grey).
12
+ * `"neutral"` (grey); on the website, `"muted"` (beige), as the category
13
+ * and date of an article (with `size="lg"`).
13
14
  * - A status: `"success"` (teal), `"info"` (blue), `"warning"` (amber) or
14
15
  * `"error"` (red).
15
16
  * @default "primary"
@@ -21,6 +22,10 @@ export type ChipProps = Omit<ComponentProps<"span">, "children" | "color"> & {
21
22
  */
22
23
  variant?: ChipVariant;
23
24
  /**
25
+ * `sm` for dense rows and inside other controls, `md` on its own, `lg` for
26
+ * the website's pills (16px semibold, 28px tall), as the category and date
27
+ * of an article or the facts of a job opening. Every colour and variant
28
+ * comes in every size.
24
29
  * @default "md"
25
30
  */
26
31
  size?: ChipSize;
@@ -0,0 +1,42 @@
1
+ import { ComponentProps, ReactElement, ReactNode } from 'react';
2
+ export type FeaturedImageProps = Omit<ComponentProps<"div">, "children"> & {
3
+ /** The photo. */
4
+ src: string;
5
+ /**
6
+ * What the photo shows, for screen readers; `""` when it is decoration
7
+ * and the text beside it says it all.
8
+ */
9
+ alt: string;
10
+ /**
11
+ * The image element to render instead of the plain `<img>`, such as
12
+ * `next/image` with `fill`: `imageRender={<NextImage src={photo} alt=""
13
+ * fill sizes="(min-width: 1024px) 50vw, 100vw" />}`, or an `<img>` with
14
+ * attributes of its own (`loading="lazy"` below the fold, `srcSet`). Its
15
+ * own props win over `src` and `alt`.
16
+ */
17
+ imageRender?: ReactElement;
18
+ /**
19
+ * A call to action on the photo, 32px from its bottom right corner: an
20
+ * `ActionButton`, `size="lg"` on wide screens and `"sm"` on phones.
21
+ */
22
+ action?: ReactNode;
23
+ };
24
+ /**
25
+ * A large photo with the website's 64px corners, and optionally a call to
26
+ * action on it, as in the website's hero grid and promo block.
27
+ *
28
+ * ```tsx
29
+ * <FeaturedImage
30
+ * src="/bilder/familie.jpg"
31
+ * alt="En familie på kjøkkenet"
32
+ * action={
33
+ * <ActionButton render={<NextLink href="/lan" />}>Se våre lån</ActionButton>
34
+ * }
35
+ * />
36
+ * ```
37
+ *
38
+ * From 1024px it fills the height its row gives it (the photo is cropped to
39
+ * fit); below that it keeps the website's 1 : 0.7. The action comes after
40
+ * the photo in the reading order.
41
+ */
42
+ export declare function FeaturedImage({ src, alt, imageRender, action, className, ...rest }: FeaturedImageProps): import("react").JSX.Element;
@@ -2,3 +2,15 @@ export * from './data-field';
2
2
  export * from './card';
3
3
  export * from './chip';
4
4
  export * from './tooltip';
5
+ export * from './avatar';
6
+ export * from './star-rating';
7
+ export * from './table';
8
+ export * from './rich-text';
9
+ export * from './featured-image';
10
+ export * from './video-player';
11
+ export * from './link-card';
12
+ export * from './media-card';
13
+ export * from './service-card';
14
+ export * from './testimonial-card';
15
+ export * from './article-card';
16
+ export * from './partner-row';
@@ -0,0 +1,52 @@
1
+ import { useRender } from '@base-ui/react/use-render';
2
+ import { ReactElement, ReactNode, Ref } from 'react';
3
+ import { SurfaceRoles } from '../color-roles';
4
+ export type LinkCardSurface = SurfaceRoles<"base" | "subtle" | "muted" | "contrast" | "contrast-accent">;
5
+ /** A link card always leads somewhere: an `href`, or a router link. */
6
+ type LinkCardTarget = {
7
+ /** Where the card leads. */
8
+ href: string;
9
+ render?: never;
10
+ } | {
11
+ href?: never;
12
+ /**
13
+ * A router link to render instead of the `<a>`, carrying its own
14
+ * destination: `render={<NextLink href="/lan" />}`.
15
+ */
16
+ render: ReactElement;
17
+ };
18
+ export type LinkCardProps = Omit<useRender.ComponentProps<"a">, "ref" | "title" | "children" | "href" | "render"> & LinkCardTarget & {
19
+ /** The rendered element: the `<a>`, or the link passed to `render`. */
20
+ ref?: Ref<HTMLElement>;
21
+ /** The text of the card, which is also the name of the link. */
22
+ title: ReactNode;
23
+ /**
24
+ * The element for the title, a `<p>` by default. Pass a heading where the
25
+ * page outline needs one: `titleRender={<h3 />}`.
26
+ */
27
+ titleRender?: ReactElement;
28
+ /**
29
+ * The colour of the card, after its `bg` token: `"base"` (white),
30
+ * `"subtle"` (grey), `"muted"` (beige), `"contrast"` (near-black) or
31
+ * `"contrast-accent"` (deep purple). On the last two the text and the
32
+ * arrow are white.
33
+ * @default "base"
34
+ */
35
+ surface?: LinkCardSurface;
36
+ };
37
+ /**
38
+ * The website's navigation card: a title and a round arrow, and the whole card
39
+ * is one link, as in the grids of links to Lån, Sparing and Forsikring.
40
+ *
41
+ * ```tsx
42
+ * <LinkCard href="/lan" title="Lån" surface="muted" />
43
+ * <LinkCard render={<NextLink href="/sparing" />} title="Sparing" surface="contrast" />
44
+ * ```
45
+ *
46
+ * On hover the card takes the website's purple tint (a dark one on the dark
47
+ * surfaces) and the arrow slides to the right. It fills the cell its grid
48
+ * gives it, at least 240px tall, with the title at the top and the arrow at
49
+ * the bottom. The link is named by the title; the arrow is decoration.
50
+ */
51
+ export declare function LinkCard({ title, titleRender, surface, render, ref, className, ...rest }: LinkCardProps): ReactElement<unknown, string | import('react').JSXElementConstructor<any>>;
52
+ export {};
@@ -0,0 +1,102 @@
1
+ import { useRender } from '@base-ui/react/use-render';
2
+ import { ReactElement, ReactNode, Ref } from 'react';
3
+ import { SurfaceRoles } from '../color-roles';
4
+ export type MediaCardSurface = SurfaceRoles<"base" | "subtle" | "muted" | "contrast" | "contrast-accent">;
5
+ export type MediaCardOrientation = "horizontal" | "vertical";
6
+ export type MediaCardImagePosition = "start" | "end";
7
+ /** `alt` is required with a photo, `""` when it is decoration. */
8
+ type MediaCardImage = {
9
+ /** The photo. Without one, the card is text only. */
10
+ src: string;
11
+ /**
12
+ * What the photo shows, for screen readers; `""` when it is decoration
13
+ * and the text says it all.
14
+ */
15
+ alt: string;
16
+ /**
17
+ * The image element to render instead of the plain `<img>`, such as
18
+ * `next/image` with `fill`, or an `<img loading="lazy">`. Its own props
19
+ * win over `src` and `alt`.
20
+ */
21
+ imageRender?: ReactElement;
22
+ } | {
23
+ src?: undefined;
24
+ alt?: undefined;
25
+ imageRender?: undefined;
26
+ };
27
+ export type MediaCardProps = Omit<useRender.ComponentProps<"div">, "ref" | "title" | "children"> & MediaCardImage & {
28
+ /**
29
+ * The rendered element: the `<div>`, or the element passed to `render`.
30
+ * A `render` element with `href` or `to` makes the whole card one link,
31
+ * named by its title: `render={<NextLink href="/lan" />}`.
32
+ */
33
+ ref?: Ref<HTMLElement>;
34
+ /** The title of the card. */
35
+ title: ReactNode;
36
+ /**
37
+ * The element for the title, an `<h2>` by default:
38
+ * `titleRender={<h3 />}`.
39
+ */
40
+ titleRender?: ReactElement;
41
+ /** The text under the title. */
42
+ text?: ReactNode;
43
+ /**
44
+ * `"horizontal"`: text and photo side by side in a coloured card, one
45
+ * above the other below 1024px. `"vertical"`: no colour of its own, the
46
+ * photo above or below centred text, for a row of cards.
47
+ * @default "horizontal"
48
+ */
49
+ orientation?: MediaCardOrientation;
50
+ /**
51
+ * Where the photo sits: `"start"` before the text (on the left, or on
52
+ * top), `"end"` after it. Left out, it is after the text on a horizontal
53
+ * card and above it on a vertical one, as on the website.
54
+ */
55
+ imagePosition?: MediaCardImagePosition;
56
+ /**
57
+ * Horizontal cards only: the photo fills its half of the card edge to
58
+ * edge, instead of sitting inside it with round corners.
59
+ * @default false
60
+ */
61
+ imageAsBackground?: boolean;
62
+ /**
63
+ * Horizontal cards only: the colour of the card, after its `bg` token.
64
+ * On `"contrast"` and `"contrast-accent"` the text is white; give a
65
+ * `Link` in `action` `color="contrast"` there.
66
+ * @default "base"
67
+ */
68
+ surface?: MediaCardSurface;
69
+ /**
70
+ * The call to action under the text: an `ActionButton`, or a `Link`
71
+ * with `arrow`. Left out when the card itself is a link, which cannot
72
+ * hold another.
73
+ */
74
+ action?: ReactNode;
75
+ /** The price example under the action, in the small print. */
76
+ priceExample?: ReactNode;
77
+ };
78
+ /**
79
+ * The website's picture-and-text card. Horizontal, it is a coloured card with
80
+ * the text in one half and the photo in the other, as the product cards on
81
+ * leabank.no's home page; vertical, it is a photo with centred text under it,
82
+ * for a row of three.
83
+ *
84
+ * ```tsx
85
+ * <MediaCard
86
+ * surface="subtle"
87
+ * title="Forbrukslån"
88
+ * text="Lån fra 10 000 til 500 000 kroner uten sikkerhet."
89
+ * src="/bilder/familie.jpg"
90
+ * alt=""
91
+ * action={<ActionButton render={<NextLink href="/lan" />}>Søk om forbrukslån</ActionButton>}
92
+ * priceExample="Eff. rente 12,5 %, 150 000 kr o/5 år …"
93
+ * />
94
+ * ```
95
+ *
96
+ * The horizontal card is two equal columns from 1024px (the photo fills its
97
+ * column), and one column below, where the photo is 1 : 0.6. A `render`
98
+ * element with `href` or `to` makes the whole card one link, named by its
99
+ * title and described by its text; it then has no `action`.
100
+ */
101
+ export declare function MediaCard({ title, titleRender, text, src, alt, imageRender, orientation, imagePosition, imageAsBackground, surface, action, priceExample, render, ref, className, ...rest }: MediaCardProps): ReactElement<unknown, string | import('react').JSXElementConstructor<any>>;
102
+ export {};
@@ -0,0 +1,46 @@
1
+ import { useRender } from '@base-ui/react/use-render';
2
+ import { ReactElement, Ref } from 'react';
3
+ /** `alt` is required with a logo. */
4
+ type PartnerRowLogo = {
5
+ /** The partner's logo, shown on a white tile. */
6
+ src: string;
7
+ /**
8
+ * The partner's name, for screen readers; `""` when the text beside
9
+ * the logo already names the partner.
10
+ */
11
+ alt: string;
12
+ /**
13
+ * The image element to render instead of the plain `<img>`, such as
14
+ * `next/image`, or an `<img loading="lazy">`. Its own props win over
15
+ * `src` and `alt`.
16
+ */
17
+ imageRender?: ReactElement;
18
+ } | {
19
+ src?: undefined;
20
+ alt?: undefined;
21
+ imageRender?: undefined;
22
+ };
23
+ export type PartnerRowProps = Omit<useRender.ComponentProps<"div">, "ref"> & PartnerRowLogo & {
24
+ /** The rendered element: the `<div>`, or the element passed to `render`. */
25
+ ref?: Ref<HTMLElement>;
26
+ };
27
+ /**
28
+ * One partner in the website's list of partners: text about the partner, and
29
+ * the logo on a white tile beside it, over a 1px line.
30
+ *
31
+ * ```tsx
32
+ * <PartnerRow src="/logoer/partner.svg" alt="">
33
+ * <RichText>
34
+ * <h3>Partner AS</h3>
35
+ * <p>Vi samarbeider med …</p>
36
+ * </RichText>
37
+ * </PartnerRow>
38
+ * ```
39
+ *
40
+ * The text is the children: usually `RichText` with the CMS content. Two
41
+ * columns 64px apart from 1024px (the tile is 240 to 360px wide and 220px
42
+ * tall), one column below. It takes the width it is given; the list
43
+ * (`PartnerList`) sets it. Pass `render={<li />}` inside a list.
44
+ */
45
+ export declare function PartnerRow({ src, alt, imageRender, render, ref, className, children, ...rest }: PartnerRowProps): ReactElement<unknown, string | import('react').JSXElementConstructor<any>>;
46
+ export {};
@@ -0,0 +1,27 @@
1
+ import { useRender } from '@base-ui/react/use-render';
2
+ import { Ref } from 'react';
3
+ export type RichTextProps = Omit<useRender.ComponentProps<"div">, "ref"> & {
4
+ /** The rendered element: the `<div>`, or the element passed to `render`. */
5
+ ref?: Ref<HTMLElement>;
6
+ };
7
+ /**
8
+ * Styles text from the CMS: headings, paragraphs, bold, italic, underline
9
+ * and strikethrough, lists, links, quotes, code and images, on Paloma's text
10
+ * styles and the website's spacing. It styles the elements inside it and
11
+ * renders nothing of its own but a `div`.
12
+ *
13
+ * ```tsx
14
+ * <RichText>{renderBlocks(blocks)}</RichText>
15
+ * ```
16
+ *
17
+ * It does not sanitise. Markup from the CMS as React elements (as the
18
+ * website's `renderBlocks` makes them) is safe as it is; an HTML string has
19
+ * to be sanitised first (the website uses DOMPurify) and goes in through
20
+ * `dangerouslySetInnerHTML`.
21
+ *
22
+ * Only bare elements are styled, the way the CMS writes them: an element with
23
+ * a class of its own, such as a Paloma `Text` or `Link`, keeps its own look.
24
+ * Headings step down on narrow screens as on the website; set `text-align`
25
+ * with `className` or `style` to centre the text.
26
+ */
27
+ export declare function RichText({ render, ref, className, ...rest }: RichTextProps): import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>>;
@@ -0,0 +1,80 @@
1
+ import { useRender } from '@base-ui/react/use-render';
2
+ import { ReactElement, ReactNode, Ref } from 'react';
3
+ import { SurfaceRoles } from '../color-roles';
4
+ export type ServiceCardSurface = SurfaceRoles<"base" | "subtle" | "muted" | "contrast" | "contrast-accent">;
5
+ export type ServiceCardLayout = "stacked" | "row";
6
+ /** `alt` is required with a photo, `""` when it is decoration. */
7
+ type ServiceCardImage = {
8
+ /** The photo. Without one, the card is text only. */
9
+ src: string;
10
+ /**
11
+ * What the photo shows, for screen readers; `""` when it is decoration
12
+ * and the text says it all.
13
+ */
14
+ alt: string;
15
+ /**
16
+ * The image element to render instead of the plain `<img>`, such as
17
+ * `next/image` with `fill`. Its own props win over `src` and `alt`.
18
+ */
19
+ imageRender?: ReactElement;
20
+ } | {
21
+ src?: undefined;
22
+ alt?: undefined;
23
+ imageRender?: undefined;
24
+ };
25
+ export type ServiceCardProps = Omit<useRender.ComponentProps<"div">, "ref" | "title" | "children"> & ServiceCardImage & {
26
+ /**
27
+ * The rendered element: the `<div>`, or the element passed to `render`.
28
+ * A `render` element with `href` or `to` makes the whole card one link,
29
+ * named by its title, as on the website: `render={<NextLink href="/lan" />}`.
30
+ */
31
+ ref?: Ref<HTMLElement>;
32
+ /** The title of the card. */
33
+ title: ReactNode;
34
+ /**
35
+ * The element for the title, an `<h2>` by default:
36
+ * `titleRender={<h3 />}`.
37
+ */
38
+ titleRender?: ReactElement;
39
+ /** The text under the title. */
40
+ text?: ReactNode;
41
+ /**
42
+ * A 40px icon above the title, such as a Lucide icon or an `<img>`.
43
+ * Mark it `aria-hidden`, or give an `<img>` `alt=""`.
44
+ */
45
+ icon?: ReactNode;
46
+ /**
47
+ * `"stacked"`: the photo fills the card above the text, for the large
48
+ * and small cells of the website's grid. `"row"`: a square photo before
49
+ * the text, for the wide cells (320px tall); stacked below 1024px.
50
+ * @default "stacked"
51
+ */
52
+ layout?: ServiceCardLayout;
53
+ /**
54
+ * The colour of the card, after its `bg` token. On `"contrast"` and
55
+ * `"contrast-accent"` the text is white.
56
+ * @default "base"
57
+ */
58
+ surface?: ServiceCardSurface;
59
+ };
60
+ /**
61
+ * A card of the website's service grid: a photo, an optional icon, a title and
62
+ * a line of text, in one of the section colours. It fills the grid cell it is
63
+ * given, and the photo takes the room the text leaves.
64
+ *
65
+ * ```tsx
66
+ * <ServiceCard
67
+ * render={<NextLink href="/lan/forbrukslan" />}
68
+ * title="Forbrukslån"
69
+ * text="Lån fra 10 000 til 500 000 kroner uten sikkerhet."
70
+ * src="/bilder/familie.jpg"
71
+ * alt=""
72
+ * surface="muted"
73
+ * />
74
+ * ```
75
+ *
76
+ * On the website the whole card is a link: pass it in `render`, and the link
77
+ * is named by the title and described by the text.
78
+ */
79
+ export declare function ServiceCard({ title, titleRender, text, icon, src, alt, imageRender, layout, surface, render, ref, className, ...rest }: ServiceCardProps): ReactElement<unknown, string | import('react').JSXElementConstructor<any>>;
80
+ export {};