Repository: FHIDev/Fhi.Designsystem
Pull request #99: 85 first button iteration
Author: login: Masuso
Created: 2025-01-28T11:42:37Z | Merged: 2025-03-26T10:35:55Z



Diff:
diff --git a/.github/workflows/pull-request.yaml b/.github/workflows/pull-request.yaml
index a4d6a2c6..098ca699 100644
--- a/.github/workflows/pull-request.yaml
+++ b/.github/workflows/pull-request.yaml
@@ -44,3 +44,10 @@ jobs:
 
       - name: Build
         run: cd packages/fhi-designsystem; pnpm build
+
+
+      - name: Prepare Testing Environment
+        run: cd packages/fhi-designsystem; pnpm exec playwright install --with-deps
+
+      - name: Test
+        run: cd packages/fhi-designsystem; pnpm test
diff --git a/packages/fhi-designsystem/src/components/fhi-button/fhi-button.docs.mdx b/packages/fhi-designsystem/src/components/fhi-button/fhi-button.docs.mdx
new file mode 100644
index 00000000..2efe18b0
--- /dev/null
+++ b/packages/fhi-designsystem/src/components/fhi-button/fhi-button.docs.mdx
@@ -0,0 +1,83 @@
+import { FhiButton } from './fhi-button.ts';
+import * as FhiButtonStories from './fhi-button.stories.ts';
+import {
+  Meta,
+  Title,
+  Primary,
+  Canvas,
+  Story,
+  Controls,
+} from '@storybook/blocks';
+
+<Meta of={FhiButtonStories} />
+
+# Button
+
+Knapper lar brukere sette i gang handlinger, som å lagre, sende inn skjemaer,
+navigere seg videre og andre spesifikke oppgaver.
+
+## Passer til
+
+- Å utføre spesifikke handlinger, slik som å sende inn et skjemasvar eller åpne en meny.
+
+- Å starte, navigere seg gjennom og avslutte en flyt eller prosess, for eksempel med «Neste» eller «Gå videre».
+
+<Canvas of={FhiButtonStories.Preview} />
+
+<Controls />
+
+## Valg
+
+Ulike varianter og størrelser kan gi knappen ulike vekter av fremheving, for å skape hierarki og veilede oppmerksomheten til brukeren.
+
+### Color (Farge)
+
+<Canvas of={FhiButtonStories.showColors} />
+
+#### `accent`
+
+Default. Knapper som skal ta oppmerksomhet og stå ut. Brukes gjerne for å gå videre eller avslutte en flyt.
+
+#### `neutral`
+
+Brukes på handlinger som ikke trenger mye oppmerksomhet. Mye bruk av `neutral` forsterker bruk av `accent`, når du trenger det.
+
+#### `danger`
+
+Signaliserer destruktive handlinger, for eksempel der data slettes eller handlinger ikke kan angres.
+
+### Variant
+
+<Canvas of={FhiButtonStories.showVariants} />
+
+#### `strong`
+
+Default. Brukes for å guide brukeren til hovedhandlingen i en kontekst. Sikt på å kun ha én synlig på skjermen til enhver tid.
+
+#### `subtle`
+
+Et mellomnivå mellom `strong` og `outlined`. Brukes for handlinger som trenger mer tyngde enn det `outline` gir, men der bruk av `strong` kan resultere i flere på samme skjerm eller blir støyende og slitsomt for brukeren.
+
+#### `outlined`
+
+Brukes til handlinger som ikke er hovedhandlinger. Kan trygt brukes mange ganger på én og samme skjerm.
+
+#### `text`
+
+Brukes på handlinger av laveste prioritet. Ofte brukt sammen med handlinger satt med andre typer knapper (f.eks. «Lagre» satt som `strong` og «Avbryt» satt i `text`).
+
+### Size (størrelse)
+
+<Canvas of={FhiButtonStories.showSizes} />
+
+#### `large`
+
+Brukes for å trekke oppmerksomhet eller som en fin avslutning etter en lengre flyt.
+
+#### `medium`
+
+Default. Brukes trygt i de fleste kontekster.
+
+#### `small`
+
+Brukes når det er lite plass til knappen eller der det er flere knapper sammen på siden og det kan bli overveldende med `medium` på alle.
diff --git a/packages/fhi-designsystem/src/components/fhi-button/fhi-button.stories.ts b/packages/fhi-designsystem/src/components/fhi-button/fhi-button.stories.ts
new file mode 100644
index 00000000..217b7419
--- /dev/null
+++ b/packages/fhi-designsystem/src/components/fhi-button/fhi-button.stories.ts
@@ -0,0 +1,118 @@
+import type { Meta, StoryObj } from '@storybook/web-components';
+import { withActions } from '@storybook/addon-actions/decorator';
+
+import { html } from 'lit';
+import { ifDefined } from 'lit/directives/if-defined.js';
+import { FhiButton } from './fhi-button';
+
+new FhiButton();
+
+const meta: Meta<FhiButton> = {
+  title: 'Komponenter/Button',
+  component: 'fhi-button',
+  parameters: {
+    actions: {
+      handles: ['click'],
+    },
+    options: { selectedPanel: 'addon-controls' },
+  },
+  decorators: [withActions],
+  render: args =>
+    html`<fhi-button
+      color=${ifDefined(args.color)}
+      variant=${ifDefined(args.variant)}
+      size=${ifDefined(args.size)}
+      type=${ifDefined(args.type)}
+      ?disabled=${args.disabled}
+    >
+      Handling
+    </fhi-button>`,
+  argTypes: {
+    color: {
+      options: ['accent', 'neutral', 'danger'],
+      control: { type: 'select' },
+      description: 'Bestemmer farge.',
+      defaultValue: { summary: 'accent' },
+    },
+    variant: {
+      options: ['strong', 'subtle', 'outlined', 'text'],
+      control: { type: 'select' },
+      description: 'Bestemmer variant.',
+      defaultValue: { summary: 'strong' },
+    },
+    size: {
+      options: ['large', 'medium', 'small'],
+      control: { type: 'select' },
+      description: 'Bestemmer størrelse.',
+      defaultValue: { summary: 'medium' },
+    },
+    type: {
+      options: ['submit', 'button', 'reset'],
+      control: { type: 'select' },
+      description: 'Bestemmer type.',
+      defaultValue: { summary: 'submit' },
+    },
+    disabled: {
+      control: { type: 'boolean' },
+      description: 'Bestemmer om knappen kan trykkes på.',
+      defaultValue: { summary: 'false' },
+    },
+  },
+};
+
+type Story = StoryObj<FhiButton>;
+
+export const Preview: Story = {
+  tags: ['!dev'],
+  args: { color: 'accent', variant: 'strong', size: 'medium' },
+};
+
+export const Accent: Story = {
+  args: { color: 'accent', variant: 'strong', size: 'medium' },
+};
+
+export const Neutral: Story = {
+  args: {
+    color: 'neutral',
+    variant: 'strong',
+    size: 'medium',
+  },
+};
+
+export const Danger: Story = {
+  args: {
+    color: 'danger',
+    variant: 'strong',
+    size: 'medium',
+  },
+};
+
+export const showColors: Story = {
+  tags: ['!dev'],
+  render: () => html`
+    <fhi-button color="accent">Handling</fhi-button>
+    <fhi-button color="neutral">Handling</fhi-button>
+    <fhi-button color="danger">Handling</fhi-button>
+  `,
+};
+
+export const showVariants: Story = {
+  tags: ['!dev'],
+  render: () => html`
+    <fhi-button color="neutral" variant="strong">Handling</fhi-button>
+    <fhi-button color="neutral" variant="subtle">Handling</fhi-button>
+    <fhi-button color="neutral" variant="outlined">Handling</fhi-button>
+    <fhi-button color="neutral" variant="text">Handling</fhi-button>
+  `,
+};
+
+export const showSizes: Story = {
+  tags: ['!dev'],
+  render: () => html`
+    <fhi-button color="neutral" size="large">Handling</fhi-button>
+    <fhi-button color="neutral" size="medium">Handling</fhi-button>
+    <fhi-button color="neutral" size="small">Handling</fhi-button>
+  `,
+};
+
+export default meta;
diff --git a/packages/fhi-designsystem/src/components/fhi-button/fhi-button.test.ts b/packages/fhi-designsystem/src/components/fhi-button/fhi-button.test.ts
new file mode 100644
index 00000000..2f0f7665
--- /dev/null
+++ b/packages/fhi-designsystem/src/components/fhi-button/fhi-button.test.ts
@@ -0,0 +1,82 @@
+import { fixture, expect } from '@open-wc/testing';
+import { html } from 'lit/static-html.js';
+
+import { FhiButton } from './fhi-button';
+
+describe('fhi-button', () => {
+  let component: FhiButton;
+
+  beforeEach(async () => {
+    component = await fixture(
+      html`<fhi-button>I am a test button</fhi-button>`,
+    );
+  });
+
+  describe('Accessibility', () => {
+    it('is accessible', async () => {
+      await expect(component).to.be.accessible();
+    });
+
+    it('is accessible when disabled', async () => {
+      component.disabled = true;
+      await component.updateComplete;
+      await expect(component).to.be.accessible();
+    });
+
+    it('is accessible as the subtle variant', async () => {
+      component.variant = 'subtle';
+      await component.updateComplete;
+      await expect(component).to.be.accessible();
+    });
+  });
+
+  describe('User interaction', () => {
+    it('should not call onClick when disabled', async () => {
+      let count = 0;
+      const onClick = (): void => {
+        count++;
+      };
+
+      component = await fixture(html`
+        <fhi-button disabled @click=${onClick}>Not clickable</fhi-button>
+      `);
+
+      expect(count).to.equal(0);
+    });
+
+    it('should handle onClick event', async () => {
+      let count = 0;
+      const onClick = (): void => {
+        count++;
+      };
+
+      component = await fixture(html`
+        <fhi-button @click=${onClick}>Click me</fhi-button>
+      `);
+
+      component.click();
+      await expect(count).to.equal(1);
+    });
+
+    it('should send click event when clicked', async () => {
+      let clicked = false;
+      component = await fixture(html` <fhi-button>Click me</fhi-button> `);
+      component.addEventListener('click', () => {
+        clicked = true;
+      });
+
+      component.click();
+      await expect(clicked).to.equal(true);
+    });
+  });
+
+  describe('API', () => {
+    it('should display child', async () => {
+      component = await fixture(
+        html`<fhi-button>Look at my child</fhi-button>`,
+      );
+
+      expect(component.textContent).to.equal(component.firstChild?.textContent);
+    });
+  });
+});
diff --git a/packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts b/packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
new file mode 100644
index 00000000..bc41a215
--- /dev/null
+++ b/packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
@@ -0,0 +1,655 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  @property({ type: String, reflect: true }) color:
+    | 'accent'
+    | 'neutral'
+    | 'danger' = 'accent';
+
+  @property({ type: String, reflect: true }) variant:
+    | 'strong'
+    | 'subtle'
+    | 'outlined'
+    | 'text' = 'strong';
+
+  @property({ type: String, reflect: true }) size:
+    | 'large'
+    | 'medium'
+    | 'small' = 'medium';
+
+  @property({ type: Boolean, reflect: true }) disabled = false;
+
+  @property({ type: String }) type: 'button' | 'submit' | 'reset' = 'submit';
+
+  private _formButton!: HTMLButtonElement;
+  private _form!: HTMLFormElement | null;
+
+  constructor() {
+    super();
+    this._stopClickLeak = this._stopClickLeak.bind(this);
+  }
+
+  override connectedCallback(): void {
+    if (!!super.connectedCallback) {
+      super.connectedCallback();
+    }
+
+    this._form = this.closest('form');
+  }
+
+  protected override firstUpdated(): void {
+    this._formButton = document.createElement('button');
+    this._formButton.addEventListener('click', this._stopClickLeak);
+    this.addEventListener('click', this._handleClick);
+  }
+
+  private _handleClick(event: MouseEvent): void {
+    if (
+      (this.type === 'submit' || this.type === 'reset') &&
+      this._form &&
+      !event.defaultPrevented
+    ) {
+      this._formButton.type = this.type;
+      this._form?.appendChild(this._formButton);
+      this._formButton.click();
+      this._form?.removeChild(this._formButton);
+    }
+  }
+
+  private _stopClickLeak(event: MouseEvent): void {
+    if (event.target === this._formButton) {
+      event.stopImmediatePropagation();
+    }
+  }
+
+  render() {
+    return html`<button ?disabled=${this.disabled} type=${this.type}>
+      <slot></slot>
+    </button>`;
+  }
+
+  static styles = css`
+    :host {
+      --dimension-border-radius: var(--fhi-border-radius-full);
+      --dimension-border-width: var(--fhi-dimension-border-width);
+      --typography-font-family: var(--fhi-font-family-roboto-flex);
+      --motion-transition: var(--fhi-motion-duration-quick)
+        var(--fhi-motion-ease-default);
+
+      --opacity-disabled: var(--fhi-opacity-disabled);
+
+      --typography-label-large-font-size: var(
+        --fhi-typography-label-large-font-size
+      );
+      --typography-label-medium-font-size: var(
+        --fhi-typography-label-medium-font-size
+      );
+      --typography-label-small-font-size: var(
+        --fhi-typography-label-medium-font-size
+      );
+      --typography-label-large-font-weight: var(
+        --fhi-typography-label-large-font-weight
+      );
+      --typography-label-medium-font-weight: var(
+        --fhi-typography-label-medium-font-weight
+      );
+      --typography-label-small-font-weight: var(
+        --fhi-typography-label-medium-font-weight
+      );
+      --typography-label-large-letter-spacing: var(
+        --fhi-typography-label-large-letter-spacing
+      );
+      --typography-label-medium-letter-spacing: var(
+        --fhi-typography-label-medium-letter-spacing
+      );
+      --typography-label-small-letter-spacing: var(
+        --fhi-typography-label-medium-letter-spacing
+      );
+      --typography-label-large-line-height: var(
+        --fhi-typography-label-large-line-height
+      );
+      --typography-label-small-line-height: var(
+        --fhi-typography-label-medium-line-height
+      );
+      --typography-label-medium-line-height: var(
+        --fhi-typography-label-medium-line-height
+      );
+
+      --dimension-padding-small: calc(
+          var(--fhi-spacing-050) - var(--fhi-dimension-border-width)
+        )
+        calc(
+          var(--fhi-spacing-150) +
+            var(--fhi-spacing-050) - var(--fhi-dimension-border-width)
+        );
+      --dimension-padding-medium: calc(
+          var(--fhi-spacing-100) - var(--fhi-dimension-border-width)
+        )
+        calc(
+          var(--fhi-spacing-200) +
+            var(--fhi-spacing-050) - var(--fhi-dimension-border-width)
+        );
+      --dimension-padding-large: calc(
+          var(--fhi-spacing-200) - var(--fhi-dimension-border-width)
+        )
+        calc(
+          var(--fhi-spacing-300) +
+            var(--fhi-spacing-050) - var(--fhi-dimension-border-width)
+        );
+      --color-accent-strong-background: var(--fhi-color-accent-base);
+      --color-accent-strong-border: var(--fhi-color-accent-base);
+      --color-accent-strong: var(--fhi-color-accent-text-inverted);
+      --color-accent-strong-background-hover: var(
+        --fhi-color-accent-base-hover
+      );
+      --color-accent-strong-border-hover: var(--fhi-color-accent-base-hover);
+      --color-accent-strong-hover: var(--fhi-color-accent-text-inverted);
+      --color-accent-strong-background-active: var(
+        --fhi-color-accent-base-active
+      );
+      --color-accent-strong-border-active: var(--fhi-color-accent-base-hover);
+      --color-accent-strong-active: var(--fhi-color-accent-text-inverted);
+      --color-accent-strong-background-disabled: var(--fhi-color-accent-base);
+      --color-accent-strong-border-disabled: var(--fhi-color-accent-base);
+      --color-accent-strong-disabled: var(--fhi-color-accent-text-inverted);
+
+      --color-accent-subtle-background: var(--fhi-color-accent-surface);
+      --color-accent-subtle-border: var(--fhi-color-accent-surface);
+      --color-accent-subtle: var(--fhi-color-accent-text-subtle);
+      --color-accent-subtle-background-hover: var(
+        --fhi-color-accent-surface-hover
+      );
+      --color-accent-subtle-border-hover: var(--fhi-color-accent-surface-hover);
+      --color-accent-subtle-hover: var(--fhi-color-accent-text);
+      --color-accent-subtle-background-active: var(
+        --fhi-color-accent-surface-active
+      );
+      --color-accent-subtle-border-active: var(
+        --fhi-color-accent-surface-active
+      );
+      --color-accent-subtle-active: var(--fhi-color-accent-text);
+      --color-accent-subtle-background-disabled: var(
+        --fhi-color-accent-surface
+      );
+      --color-accent-subtle-border-disabled: var(--fhi-color-accent-surface);
+      --color-accent-subtle-disabled: var(--fhi-color-accent-text-subtle);
+
+      --color-accent-outlined-background: transparent;
+      --color-accent-outlined-border: var(--fhi-color-accent-border-subtle);
+      --color-accent-outlined: var(--fhi-color-accent-text-subtle);
+      --color-accent-outlined-background-hover: var(--fhi-color-accent-surface);
+      --color-accent-outlined-border-hover: var(--fhi-color-accent-surface);
+      --color-accent-outlined-hover: var(--fhi-color-accent-text);
+      --color-accent-outlined-background-active: var(
+        --fhi-color-accent-surface-hover
+      );
+      --color-accent-outlined-border-active: var(
+        --fhi-color-accent-surface-hover
+      );
+      --color-accent-outlined-active: var(--fhi-color-accent-text);
+      --color-accent-outlined-background-disabled: transparent;
+      --color-accent-outlined-border-disabled: var(
+        --fhi-color-accent-border-subtle
+      );
+      --color-accent-outlined-disabled: var(--fhi-color-accent-text-subtle);
+
+      --color-accent-text-background: transparent;
+      --color-accent-text-border: transparent;
+      --color-accent-text: var(--fhi-color-accent-text-subtle);
+      --color-accent-text-background-hover: var(--fhi-color-accent-surface);
+      --color-accent-text-border-hover: var(--fhi-color-accent-surface);
+      --color-accent-text-hover: var(--fhi-color-accent-text);
+      --color-accent-text-background-active: var(
+        --fhi-color-accent-surface-hover
+      );
+      --color-accent-text-border-active: var(--fhi-color-accent-surface-hover);
+      --color-accent-text-active: var(--fhi-color-accent-text);
+      --color-accent-text-background-disabled: transparent;
+      --color-accent-text-border-disabled: transparent;
+      --color-accent-text-disabled: var(--fhi-color-accent-text);
+
+      --color-neutral-strong-background: var(--fhi-color-neutral-base);
+      --color-neutral-strong-border: var(--fhi-color-neutral-base);
+      --color-neutral-strong: var(--fhi-color-neutral-text-inverted);
+      --color-neutral-strong-background-hover: var(
+        --fhi-color-neutral-base-hover
+      );
+      --color-neutral-strong-border-hover: var(--fhi-color-neutral-base-hover);
+      --color-neutral-strong-hover: var(--fhi-color-neutral-text-inverted);
+      --color-neutral-strong-background-active: var(
+        --fhi-color-neutral-base-active
+      );
+      --color-neutral-strong-border-active: var(--fhi-color-neutral-base-hover);
+      --color-neutral-strong-active: var(--fhi-color-neutral-text-inverted);
+      --color-neutral-strong-background-disabled: var(--fhi-color-neutral-base);
+      --color-neutral-strong-border-disabled: var(--fhi-color-neutral-base);
+      --color-neutral-strong-disabled: var(--fhi-color-neutral-text-inverted);
+
+      --color-neutral-subtle-background: var(--fhi-color-neutral-surface);
+      --color-neutral-subtle-border: var(--fhi-color-neutral-surface);
+      --color-neutral-subtle: var(--fhi-color-neutral-text-subtle);
+      --color-neutral-subtle-background-hover: var(
+        --fhi-color-neutral-surface-hover
+      );
+      --color-neutral-subtle-border-hover: var(
+        --fhi-color-neutral-surface-hover
+      );
+      --color-neutral-subtle-hover: var(--fhi-color-neutral-text);
+      --color-neutral-subtle-background-active: var(
+        --fhi-color-neutral-surface-active
+      );
+      --color-neutral-subtle-border-active: var(
+        --fhi-color-neutral-surface-active
+      );
+      --color-neutral-subtle-active: var(--fhi-color-neutral-text);
+      --color-neutral-subtle-background-disabled: var(
+        --fhi-color-neutral-surface
+      );
+      --color-neutral-subtle-border-disabled: var(--fhi-color-neutral-surface);
+      --color-neutral-subtle-disabled: var(--fhi-color-neutral-text);
+
+      --color-neutral-outlined-background: transparent;
+      --color-neutral-outlined-border: var(--fhi-color-neutral-border-subtle);
+      --color-neutral-outlined: var(--fhi-color-neutral-text-subtle);
+      --color-neutral-outlined-background-hover: var(
+        --fhi-color-neutral-surface
+      );
+      --color-neutral-outlined-border-hover: var(--fhi-color-neutral-surface);
+      --color-neutral-outlined-hover: var(--fhi-color-neutral-text);
+      --color-neutral-outlined-background-active: var(
+        --fhi-color-neutral-surface-hover
+      );
+      --color-neutral-outlined-border-active: var(
+        --fhi-color-neutral-surface-hover
+      );
+      --color-neutral-outlined-active: var(--fhi-color-neutral-text);
+      --color-neutral-outlined-background-disabled: transparent;
+      --color-neutral-outlined-border-disabled: var(
+        --fhi-color-neutral-border-subtle
+      );
+      --color-neutral-outlined-disabled: var(--fhi-color-neutral-text-subtle);
+
+      --color-neutral-text-background: transparent;
+      --color-neutral-text-border: transparent;
+      --color-neutral-text: var(--fhi-color-neutral-text-subtle);
+      --color-neutral-text-background-hover: var(--fhi-color-neutral-surface);
+      --color-neutral-text-border-hover: var(--fhi-color-neutral-surface);
+      --color-neutral-text-hover: var(--fhi-color-neutral-text);
+      --color-neutral-text-background-active: var(
+        --fhi-color-neutral-surface-hover
+      );
+      --color-neutral-text-border-active: var(
+        --fhi-color-neutral-surface-hover
+      );
+      --color-neutral-text-active: var(--fhi-color-neutral-text);
+      --color-neutral-text-background-disabled: transparent;
+      --color-neutral-text-border-disabled: transparent;
+      --color-neutral-text-disabled: var(--fhi-color-neutral-text-subtle);
+
+      --color-danger-strong-background: var(--fhi-color-danger-base);
+      --color-danger-strong-border: var(--fhi-color-danger-base);
+      --color-danger-strong: var(--fhi-color-danger-text-inverted);
+      --color-danger-strong-background-hover: var(
+        --fhi-color-danger-base-hover
+      );
+      --color-danger-strong-border-hover: var(--fhi-color-danger-base-hover);
+      --color-danger-strong-hover: var(--fhi-color-danger-text-inverted);
+      --color-danger-strong-background-active: var(
+        --fhi-color-danger-base-active
+      );
+      --color-danger-strong-border-active: var(--fhi-color-danger-base-hover);
+      --color-danger-strong-active: var(--fhi-color-danger-text-inverted);
+      --color-danger-strong-background-disabled: var(--fhi-color-danger-base);
+      --color-danger-strong-border-disabled: var(--fhi-color-danger-base);
+      --color-danger-strong-disabled: var(--fhi-color-danger-text-inverted);
+
+      --color-danger-subtle-background: var(--fhi-color-danger-surface);
+      --color-danger-subtle-border: var(--fhi-color-danger-surface);
+      --color-danger-subtle: var(--fhi-color-danger-text-subtle);
+      --color-danger-subtle-background-hover: var(
+        --fhi-color-danger-surface-hover
+      );
+      --color-danger-subtle-border-hover: var(--fhi-color-danger-surface-hover);
+      --color-danger-subtle-hover: var(--fhi-color-danger-text);
+      --color-danger-subtle-background-active: var(
+        --fhi-color-danger-surface-active
+      );
+      --color-danger-subtle-border-active: var(
+        --fhi-color-danger-surface-active
+      );
+      --color-danger-subtle-active: var(--fhi-color-danger-text);
+      --color-danger-subtle-background-disabled: var(
+        --fhi-color-danger-surface
+      );
+      --color-danger-subtle-border-disabled: var(--fhi-color-danger-surface);
+      --color-danger-subtle-disabled: var(--fhi-color-danger-text-subtle);
+
+      --color-danger-outlined-background: transparent;
+      --color-danger-outlined-border: var(--fhi-color-danger-border-subtle);
+      --color-danger-outlined: var(--fhi-color-danger-text-subtle);
+      --color-danger-outlined-background-hover: var(--fhi-color-danger-surface);
+      --color-danger-outlined-border-hover: var(--fhi-color-danger-surface);
+      --color-danger-outlined-hover: var(--fhi-color-danger-text);
+      --color-danger-outlined-background-active: var(
+        --fhi-color-danger-surface-hover
+      );
+      --color-danger-outlined-border-active: var(
+        --fhi-color-danger-surface-hover
+      );
+      --color-danger-outlined-active: var(--fhi-color-danger-text);
+      --color-danger-outlined-background-disabled: transparent;
+      --color-danger-outlined-border-disabled: var(
+        --fhi-color-danger-border-subtle
+      );
+      --color-danger-outlined-disabled: var(--fhi-color-danger-text-subtle);
+
+      --color-danger-text-background: transparent;
+      --color-danger-text-border: transparent;
+      --color-danger-text: var(--fhi-color-danger-text-subtle);
+      --color-danger-text-background-hover: var(--fhi-color-danger-surface);
+      --color-danger-text-border-hover: var(--fhi-color-danger-surface);
+      --color-danger-text-hover: var(--fhi-color-danger-text);
+      --color-danger-text-background-active: var(
+        --fhi-color-danger-surface-hover
+      );
+      --color-danger-text-border-active: var(--fhi-color-danger-surface-hover);
+      --color-danger-text-active: var(--fhi-color-danger-text);
+      --color-danger-text-background-disabled: transparent;
+      --color-danger-text-border-disabled: transparent;
+      --color-danger-text-disabled: var(--fhi-color-danger-text-subtle);
+
+      button {
+        border-radius: var(--dimension-border-radius);
+        border: solid var(--dimension-border-width);
+        font-family: var(--typography-font-family);
+        transition: var(--motion-transition);
+
+        cursor: pointer;
+        &:disabled {
+          opacity: var(--opacity-disabled);
+          cursor: not-allowed;
+        }
+      }
+    }
+
+    :host([size='large']) button {
+      font-size: var(--typography-label-large-font-size);
+      font-weight: var(--typography-label-large-font-weight);
+      line-height: var(--typography-label-large-line-height);
+      letter-spacing: var(--typography-label-large-letter-spacing);
+      padding: var(--dimension-padding-large);
+    }
+
+    :host([size='medium']) button {
+      font-size: var(--typography-label-medium-font-size);
+      font-weight: var(--typography-label-medium-font-weight);
+      line-height: var(--typography-label-medium-line-height);
+      letter-spacing: var(--typography-label-medium-letter-spacing);
+      padding: var(--dimension-padding-medium);
+    }
+
+    :host([size='small']) button {
+      font-size: var(--typography-label-small-font-size);
+      font-weight: var(--typography-label-small-font-weight);
+      line-height: var(--typography-label-small-line-height);
+      letter-spacing: var(--typography-label-small-letter-spacing);
+      padding: var(--dimension-padding-small);
+    }
+
+    :host([color='accent'][variant='strong']) button {
+      background-color: var(--color-accent-strong-background);
+      border-color: var(--color-accent-strong-border);
+      color: var(--color-accent-strong);
+      &:hover {
+        background-color: var(--color-accent-strong-background-hover);
+        border-color: var(--color-accent-strong-border-hover);
+        color: var(--color-accent-strong-hover);
+      }
+      &:active {
+        background-color: var(--color-accent-strong-background-active);
+        border-color: var(--color-accent-strong-border-active);
+        color: var(--color-accent-strong-active);
+      }
+      &:disabled {
+        background-color: var(--color-accent-strong-background-disabled);
+        border-color: var(--color-accent-strong-border-disabled);
+        color: var(--color-accent-strong-disabled);
+      }
+    }
+
+    :host([color='accent'][variant='subtle']) button {
+      background-color: var(--color-accent-subtle-background);
+      border-color: var(--color-accent-subtle-border);
+      color: var(--color-accent-subtle);
+      &:hover {
+        background-color: var(--color-accent-subtle-background-hover);
+        border-color: var(--color-accent-subtle-border-hover);
+        color: var(--color-accent-subtle-hover);
+      }
+      &:active {
+        background-color: var(--color-accent-subtle-background-active);
+        border-color: var(--color-accent-subtle-border-active);
+        color: var(--color-accent-subtle-active);
+      }
+      &:disabled {
+        background-color: var(--color-accent-subtle-background-disabled);
+        border-color: var(--color-accent-subtle-border-disabled);
+        color: var(--color-accent-subtle-disabled);
+      }
+    }
+
+    :host([color='accent'][variant='outlined']) button {
+      background-color: var(--color-accent-outlined-background);
+      border-color: var(--color-accent-outlined-border);
+      color: var(--color-accent-outlined);
+      &:hover {
+        background-color: var(--color-accent-outlined-background-hover);
+        border-color: var(--color-accent-outlined-border-hover);
+        color: var(--color-accent-outlined-hover);
+      }
+      &:active {
+        background-color: var(--color-accent-outlined-background-active);
+        border-color: var(--color-accent-outlined-border-active);
+        color: var(--color-accent-outlined-active);
+      }
+      &:disabled {
+        background-color: var(--color-accent-outlined-background-disabled);
+        border-color: var(--color-accent-outlined-border-disabled);
+        color: var(--color-accent-outlined-disabled);
+      }
+    }
+
+    :host([color='accent'][variant='text']) button {
+      background-color: var(--color-accent-text-background);
+      border-color: var(--color-accent-text-border);
+      color: var(--color-accent-text);
+      &:hover {
+        background-color: var(--color-accent-text-background-hover);
+        border-color: var(--color-accent-text-border-hover);
+        color: var(--color-accent-text-hover);
+      }
+      &:active {
+        background-color: var(--color-accent-text-background-active);
+        border-color: var(--color-accent-text-border-active);
+        color: var(--color-accent-text-active);
+      }
+      &:disabled {
+        background-color: var(--color-accent-text-background-disabled);
+        border-color: var(--color-accent-text-border-disabled);
+        color: var(--color-accent-text-disabled);
+      }
+    }
+
+    :host([color='neutral'][variant='strong']) button {
+      background-color: var(--color-neutral-strong-background);
+      border-color: var(--color-neutral-strong-border);
+      color: var(--color-neutral-strong);
+      &:hover {
+        background-color: var(--color-neutral-strong-background-hover);
+        border-color: var(--color-neutral-strong-border-hover);
+        color: var(--color-neutral-strong-hover);
+      }
+      &:active {
+        background-color: var(--color-neutral-strong-background-active);
+        border-color: var(--color-neutral-strong-border-active);
+        color: var(--color-neutral-strong-active);
+      }
+      &:disabled {
+        background-color: var(--color-neutral-strong-background-disabled);
+        border-color: var(--color-neutral-strong-border-disabled);
+        color: var(--color-neutral-strong-disabled);
+      }
+    }
+
+    :host([color='neutral'][variant='subtle']) button {
+      background-color: var(--color-neutral-subtle-background);
+      border-color: var(--color-neutral-subtle-border);
+      color: var(--color-neutral-subtle);
+      &:hover {
+        background-color: var(--color-neutral-subtle-background-hover);
+        border-color: var(--color-neutral-subtle-border-hover);
+        color: var(--color-neutral-subtle-hover);
+      }
+      &:active {
+        background-color: var(--color-neutral-subtle-background-active);
+        border-color: var(--color-neutral-subtle-border-active);
+        color: var(--color-neutral-subtle-active);
+      }
+      &:disabled {
+        background-color: var(--color-neutral-subtle-background-disabled);
+        border-color: var(--color-neutral-subtle-border-disabled);
+        color: var(--color-neutral-subtle-disabled);
+      }
+    }
+
+    :host([color='neutral'][variant='outlined']) button {
+      background-color: var(--color-neutral-outlined-background);
+      border-color: var(--color-neutral-outlined-border);
+      color: var(--color-neutral-outlined);
+      &:hover {
+        background-color: var(--color-neutral-outlined-background-hover);
+        border-color: var(--color-neutral-outlined-border-hover);
+        color: var(--color-neutral-outlined-hover);
+      }
+      &:active {
+        background-color: var(--color-neutral-outlined-background-active);
+        border-color: var(--color-neutral-outlined-border-active);
+        color: var(--color-neutral-outlined-active);
+      }
+      &:disabled {
+        background-color: var(--color-neutral-outlined-background-disabled);
+        border-color: var(--color-neutral-outlined-border-disabled);
+        color: var(--color-neutral-outlined-disabled);
+      }
+    }
+
+    :host([color='neutral'][variant='text']) button {
+      background-color: var(--color-neutral-text-background);
+      border-color: var(--color-neutral-text-border);
+      color: var(--color-neutral-text);
+      &:hover {
+        background-color: var(--color-neutral-text-background-hover);
+        border-color: var(--color-neutral-text-border-hover);
+        color: var(--color-neutral-text-hover);
+      }
+      &:active {
+        background-color: var(--color-neutral-text-background-active);
+        border-color: var(--color-neutral-text-border-active);
+        color: var(--color-neutral-text-active);
+      }
+      &:disabled {
+        background-color: var(--color-neutral-text-background-disabled);
+        border-color: var(--color-neutral-text-border-disabled);
+        color: var(--color-neutral-text-disabled);
+      }
+    }
+
+    :host([color='danger'][variant='strong']) button {
+      background-color: var(--color-danger-strong-background);
+      border-color: var(--color-danger-strong-border);
+      color: var(--color-danger-strong);
+      &:hover {
+        background-color: var(--color-danger-strong-background-hover);
+        border-color: var(--color-danger-strong-border-hover);
+        color: var(--color-danger-strong-hover);
+      }
+      &:active {
+        background-color: var(--color-danger-strong-background-active);
+        border-color: var(--color-danger-strong-border-active);
+        color: var(--color-danger-strong-active);
+      }
+      &:disabled {
+        background-color: var(--color-danger-strong-background-disabled);
+        border-color: var(--color-danger-strong-border-disabled);
+        color: var(--color-danger-strong-disabled);
+      }
+    }
+
+    :host([color='danger'][variant='subtle']) button {
+      background-color: var(--color-danger-subtle-background);
+      border-color: var(--color-danger-subtle-border);
+      color: var(--color-danger-subtle);
+      &:hover {
+        background-color: var(--color-danger-subtle-background-hover);
+        border-color: var(--color-danger-subtle-border-hover);
+        color: var(--color-danger-subtle-hover);
+      }
+      &:active {
+        background-color: var(--color-danger-subtle-background-active);
+        border-color: var(--color-danger-subtle-border-active);
+        color: var(--color-danger-subtle-active);
+      }
+      &:disabled {
+        background-color: var(--color-danger-subtle-background-disabled);
+        border-color: var(--color-danger-subtle-border-disabled);
+        color: var(--color-danger-subtle-disabled);
+      }
+    }
+
+    :host([color='danger'][variant='outlined']) button {
+      background-color: var(--color-danger-outlined-background);
+      border-color: var(--color-danger-outlined-border);
+      color: var(--color-danger-outlined);
+      &:hover {
+        background-color: var(--color-danger-outlined-background-hover);
+        border-color: var(--color-danger-outlined-border-hover);
+        color: var(--color-danger-outlined-hover);
+      }
+      &:active {
+        background-color: var(--color-danger-outlined-background-active);
+        border-color: var(--color-danger-outlined-border-active);
+        color: var(--color-danger-outlined-active);
+      }
+      &:disabled {
+        background-color: var(--color-danger-outlined-background-disabled);
+        border-color: var(--color-danger-outlined-border-disabled);
+        color: var(--color-danger-outlined-disabled);
+      }
+    }
+
+    :host([color='danger'][variant='text']) button {
+      background-color: var(--color-danger-text-background);
+      border-color: var(--color-danger-text-border);
+      color: var(--color-danger-text);
+      &:hover {
+        background-color: var(--color-danger-text-background-hover);
+        border-color: var(--color-danger-text-border-hover);
+        color: var(--color-danger-text-hover);
+      }
+      &:active {
+        background-color: var(--color-danger-text-background-active);
+        border-color: var(--color-danger-text-border-active);
+        color: var(--color-danger-text-active);
+      }
+      &:disabled {
+        background-color: var(--color-danger-text-background-disabled);
+        border-color: var(--color-danger-text-border-disabled);
+        color: var(--color-danger-text-disabled);
+      }
+    }
+  `;
+}
diff --git a/packages/fhi-designsystem/src/library.ts b/packages/fhi-designsystem/src/library.ts
index 5420bfb6..bdc31a17 100644
--- a/packages/fhi-designsystem/src/library.ts
+++ b/packages/fhi-designsystem/src/library.ts
@@ -1,2 +1,3 @@
 // e.g:
 // export * from './components/new-component/new-component.ts';
+export * from './components/fhi-button/fhi-button.ts';
diff --git a/packages/fhi-designsystem/src/storybook/getting_started.mdx b/packages/fhi-designsystem/src/storybook/getting_started.mdx
index 741dd0a0..a8250bcb 100644
--- a/packages/fhi-designsystem/src/storybook/getting_started.mdx
+++ b/packages/fhi-designsystem/src/storybook/getting_started.mdx
@@ -1,6 +1,6 @@
 import { Meta } from '@storybook/blocks';
 
-<Meta title="FHI Designsystem/Kom i gang" />
+<Meta title="Kom i gang" />
  
 # Velkommen til FHI Designsystem!
 
diff --git a/packages/fhi-designsystem/vite.config.js b/packages/fhi-designsystem/vite.config.js
index 3ccf86e4..28efa48b 100644
--- a/packages/fhi-designsystem/vite.config.js
+++ b/packages/fhi-designsystem/vite.config.js
@@ -70,6 +70,7 @@ export default defineConfig(({ mode }) => {
                 If you create a new component you need to add a reference to it here, e.g:
                 "new-component": "./src/components/new-component/new-component.ts",
             */
+              'fhi-button': './src/components/fhi-button/fhi-button.ts',
               index: './src/library.ts',
             },
           },


Reviews:
user: login: proand
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-06T14:16:31Z
user: login: proand
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-06T14:17:47Z
user: login: proand
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-06T14:19:29Z
user: login: dafn
state: CHANGES_REQUESTED
author_association: COLLABORATOR
submitted_at: 2025-02-07T10:19:33Z
user: login: dafn
state: CHANGES_REQUESTED
author_association: COLLABORATOR
submitted_at: 2025-02-07T10:20:17Z
user: login: proand
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-07T11:01:22Z
user: login: trybern
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-07T11:53:00Z
user: login: dafn
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-02-11T09:53:19Z
user: login: trybern
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-12T06:43:41Z
user: login: trybern
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-13T10:33:06Z
user: login: dafn
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-02-21T09:22:08Z
user: login: dafn
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-02-25T13:07:46Z
user: login: dafn
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-02-26T13:46:25Z
user: login: dafn
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-02-26T13:48:01Z
user: login: Masuso
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-27T10:35:47Z
user: login: dafn
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-06T09:15:37Z
user: login: proand
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-10T09:07:19Z
user: login: Masuso
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-10T09:14:40Z
user: login: dafn
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-12T14:52:24Z
user: login: dafn
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-12T15:01:28Z
user: login: trybern
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-12T15:27:11Z
user: login: trybern
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-12T15:33:00Z
user: login: dafn
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-13T09:02:46Z
user: login: trybern
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-17T10:04:05Z
user: login: trybern
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-26T07:52:18Z
user: login: trybern
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-26T10:30:19Z
user: login: dafn
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-03-26T10:31:13Z

Review comments:
diff_hunk: @@ -0,0 +1,63 @@
+import { FhiButton } from './fhi-button.ts';
+import * as FhiButtonStories from './fhi-button.stories.ts';
+import {
+  Meta,
+  Title,
+  Primary,
+  Canvas,
+  Story,
+  Controls,
+} from '@storybook/blocks';
+
+<Meta of={FhiButtonStories} />
+
+# Button
+
+Knapper lar brukere sette i gang handlinger, som å lagre, sende inn skjemaer,
+navigere seg videre og andre spesifikke oppgaver.
+
+## Passer til
+
+- Å utføre spesifikke handling, slik som å sende inn et skjemasvar eller åpne en meny.
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.docs.mdx
user: login: proand
body: spesifikke handling -> spesifikke handlinger
created_at: 2025-02-06T14:16:31Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,388 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+export type FhiButtonProps = Pick<
+  FhiButton,
+  'color' | 'variant' | 'disabled' | 'size'
+>;
+
+/**
+ * Button component
+ *
+ * @tag fhi-button
+ *
+ * @slot contains the content of the button
+ *
+ */
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  /**
+   * Bestemmer fargen på knappen.
+   * @default 'accent'
+   */
+  @property({ type: String, reflect: true }) color:
+    | 'accent'
+    | 'neutral'
+    | 'danger' = 'accent';
+
+  /**
+   * Bestemmer varianten av knappen.
+   * @default 'strong'
+   */
+  @property({ type: String, reflect: true }) variant:
+    | 'strong'
+    | 'subtle'
+    | 'outlined'
+    | 'text' = 'strong';
+
+  /**
+   * Bestemmer størrelsen på knappen.
+   * @default 'medium'
+   */
+  @property({ type: String, reflect: true }) size?:
+    | 'large'
+    | 'medium'
+    | 'small' = 'medium';
+
+  /**
+   * Bestemmer om knappen er tilgjengelig.
+   * @deafult false
+   */
+  @property({ type: Boolean, reflect: true }) disabled = false;
+
+  render() {
+    return html`<button ?disabled=${this.disabled}>
+      <slot></slot>
+    </button>`;
+  }
+
+  static styles = css`
+    :host {
+      button {
+        border-radius: var(--fhi-border-radius-full);
+        border-style: inset;
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: proand
body: `inset` blir overskrevet av `solid`, altså redundant
created_at: 2025-02-06T14:17:47Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,388 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+export type FhiButtonProps = Pick<
+  FhiButton,
+  'color' | 'variant' | 'disabled' | 'size'
+>;
+
+/**
+ * Button component
+ *
+ * @tag fhi-button
+ *
+ * @slot contains the content of the button
+ *
+ */
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  /**
+   * Bestemmer fargen på knappen.
+   * @default 'accent'
+   */
+  @property({ type: String, reflect: true }) color:
+    | 'accent'
+    | 'neutral'
+    | 'danger' = 'accent';
+
+  /**
+   * Bestemmer varianten av knappen.
+   * @default 'strong'
+   */
+  @property({ type: String, reflect: true }) variant:
+    | 'strong'
+    | 'subtle'
+    | 'outlined'
+    | 'text' = 'strong';
+
+  /**
+   * Bestemmer størrelsen på knappen.
+   * @default 'medium'
+   */
+  @property({ type: String, reflect: true }) size?:
+    | 'large'
+    | 'medium'
+    | 'small' = 'medium';
+
+  /**
+   * Bestemmer om knappen er tilgjengelig.
+   * @deafult false
+   */
+  @property({ type: Boolean, reflect: true }) disabled = false;
+
+  render() {
+    return html`<button ?disabled=${this.disabled}>
+      <slot></slot>
+    </button>`;
+  }
+
+  static styles = css`
+    :host {
+      button {
+        border-radius: var(--fhi-border-radius-full);
+        border-style: inset;
+        border: 1px solid;
+        font-family: var(--fhi-font-family-roboto-flex);
+
+        display: inline-flex;
+        justify-content: center;
+        align-items: center;
+        transition-duration: var(--fhi-duration-slow);
+
+        cursor: pointer;
+        &:disabled {
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: proand
body: Vi bør kanskje bli enige om noen syntax-regler for css; linjeskift, rekkefølge osv... bare et innspill til diskusjon 🙂 
created_at: 2025-02-06T14:19:29Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,388 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+export type FhiButtonProps = Pick<
+  FhiButton,
+  'color' | 'variant' | 'disabled' | 'size'
+>;
+
+/**
+ * Button component
+ *
+ * @tag fhi-button
+ *
+ * @slot contains the content of the button
+ *
+ */
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  /**
+   * Bestemmer fargen på knappen.
+   * @default 'accent'
+   */
+  @property({ type: String, reflect: true }) color:
+    | 'accent'
+    | 'neutral'
+    | 'danger' = 'accent';
+
+  /**
+   * Bestemmer varianten av knappen.
+   * @default 'strong'
+   */
+  @property({ type: String, reflect: true }) variant:
+    | 'strong'
+    | 'subtle'
+    | 'outlined'
+    | 'text' = 'strong';
+
+  /**
+   * Bestemmer størrelsen på knappen.
+   * @default 'medium'
+   */
+  @property({ type: String, reflect: true }) size?:
+    | 'large'
+    | 'medium'
+    | 'small' = 'medium';
+
+  /**
+   * Bestemmer om knappen er tilgjengelig.
+   * @deafult false
+   */
+  @property({ type: Boolean, reflect: true }) disabled = false;
+
+  render() {
+    return html`<button ?disabled=${this.disabled}>
+      <slot></slot>
+    </button>`;
+  }
+
+  static styles = css`
+    :host {
+      button {
+        border-radius: var(--fhi-border-radius-full);
+        border-style: inset;
+        border: 1px solid;
+        font-family: var(--fhi-font-family-roboto-flex);
+
+        display: inline-flex;
+        justify-content: center;
+        align-items: center;
+        transition-duration: var(--fhi-duration-slow);
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: trybern
body: ```suggestion
        transition-duration: var(--fhi-duration-quick);
```
created_at: 2025-02-07T09:39:35Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,388 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+export type FhiButtonProps = Pick<
+  FhiButton,
+  'color' | 'variant' | 'disabled' | 'size'
+>;
+
+/**
+ * Button component
+ *
+ * @tag fhi-button
+ *
+ * @slot contains the content of the button
+ *
+ */
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  /**
+   * Bestemmer fargen på knappen.
+   * @default 'accent'
+   */
+  @property({ type: String, reflect: true }) color:
+    | 'accent'
+    | 'neutral'
+    | 'danger' = 'accent';
+
+  /**
+   * Bestemmer varianten av knappen.
+   * @default 'strong'
+   */
+  @property({ type: String, reflect: true }) variant:
+    | 'strong'
+    | 'subtle'
+    | 'outlined'
+    | 'text' = 'strong';
+
+  /**
+   * Bestemmer størrelsen på knappen.
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: dafn
body: Comments in code should be in english
created_at: 2025-02-07T09:40:48Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,388 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+export type FhiButtonProps = Pick<
+  FhiButton,
+  'color' | 'variant' | 'disabled' | 'size'
+>;
+
+/**
+ * Button component
+ *
+ * @tag fhi-button
+ *
+ * @slot contains the content of the button
+ *
+ */
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  /**
+   * Bestemmer fargen på knappen.
+   * @default 'accent'
+   */
+  @property({ type: String, reflect: true }) color:
+    | 'accent'
+    | 'neutral'
+    | 'danger' = 'accent';
+
+  /**
+   * Bestemmer varianten av knappen.
+   * @default 'strong'
+   */
+  @property({ type: String, reflect: true }) variant:
+    | 'strong'
+    | 'subtle'
+    | 'outlined'
+    | 'text' = 'strong';
+
+  /**
+   * Bestemmer størrelsen på knappen.
+   * @default 'medium'
+   */
+  @property({ type: String, reflect: true }) size?:
+    | 'large'
+    | 'medium'
+    | 'small' = 'medium';
+
+  /**
+   * Bestemmer om knappen er tilgjengelig.
+   * @deafult false
+   */
+  @property({ type: Boolean, reflect: true }) disabled = false;
+
+  render() {
+    return html`<button ?disabled=${this.disabled}>
+      <slot></slot>
+    </button>`;
+  }
+
+  static styles = css`
+    :host {
+      button {
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: dafn
body: these `button` selectors can be declared inline with the `:host` selector. Minor, but it will save 2 lines per `:host` block.

e.g `:host button {...}`
created_at: 2025-02-07T09:42:23Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,388 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+export type FhiButtonProps = Pick<
+  FhiButton,
+  'color' | 'variant' | 'disabled' | 'size'
+>;
+
+/**
+ * Button component
+ *
+ * @tag fhi-button
+ *
+ * @slot contains the content of the button
+ *
+ */
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  /**
+   * Bestemmer fargen på knappen.
+   * @default 'accent'
+   */
+  @property({ type: String, reflect: true }) color:
+    | 'accent'
+    | 'neutral'
+    | 'danger' = 'accent';
+
+  /**
+   * Bestemmer varianten av knappen.
+   * @default 'strong'
+   */
+  @property({ type: String, reflect: true }) variant:
+    | 'strong'
+    | 'subtle'
+    | 'outlined'
+    | 'text' = 'strong';
+
+  /**
+   * Bestemmer størrelsen på knappen.
+   * @default 'medium'
+   */
+  @property({ type: String, reflect: true }) size?:
+    | 'large'
+    | 'medium'
+    | 'small' = 'medium';
+
+  /**
+   * Bestemmer om knappen er tilgjengelig.
+   * @deafult false
+   */
+  @property({ type: Boolean, reflect: true }) disabled = false;
+
+  render() {
+    return html`<button ?disabled=${this.disabled}>
+      <slot></slot>
+    </button>`;
+  }
+
+  static styles = css`
+    :host {
+      button {
+        border-radius: var(--fhi-border-radius-full);
+        border-style: inset;
+        border: 1px solid;
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: dafn
body: Here you can use `--fhi-border-width`
created_at: 2025-02-07T09:46:17Z
author_association: COLLABORATOR
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.test.ts
user: login: dafn
body: You should add some tests for `form` interactions
created_at: 2025-02-07T09:47:28Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,61 @@
+import { fixture, expect } from '@open-wc/testing';
+import { html } from 'lit/static-html.js';
+
+import { FhiButton } from './fhi-button';
+
+describe('fhi-button', () => {
+  let component: FhiButton;
+
+  beforeEach(async () => {
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.test.ts
user: login: dafn
body: This can be moved into the`Accessibility` test desciption block
created_at: 2025-02-07T09:49:06Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,388 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+export type FhiButtonProps = Pick<
+  FhiButton,
+  'color' | 'variant' | 'disabled' | 'size'
+>;
+
+/**
+ * Button component
+ *
+ * @tag fhi-button
+ *
+ * @slot contains the content of the button
+ *
+ */
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  /**
+   * Bestemmer fargen på knappen.
+   * @default 'accent'
+   */
+  @property({ type: String, reflect: true }) color:
+    | 'accent'
+    | 'neutral'
+    | 'danger' = 'accent';
+
+  /**
+   * Bestemmer varianten av knappen.
+   * @default 'strong'
+   */
+  @property({ type: String, reflect: true }) variant:
+    | 'strong'
+    | 'subtle'
+    | 'outlined'
+    | 'text' = 'strong';
+
+  /**
+   * Bestemmer størrelsen på knappen.
+   * @default 'medium'
+   */
+  @property({ type: String, reflect: true }) size?:
+    | 'large'
+    | 'medium'
+    | 'small' = 'medium';
+
+  /**
+   * Bestemmer om knappen er tilgjengelig.
+   * @deafult false
+   */
+  @property({ type: Boolean, reflect: true }) disabled = false;
+
+  render() {
+    return html`<button ?disabled=${this.disabled}>
+      <slot></slot>
+    </button>`;
+  }
+
+  static styles = css`
+    :host {
+      button {
+        border-radius: var(--fhi-border-radius-full);
+        border-style: inset;
+        border: 1px solid;
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: trybern
body: Vi bruker skalaer som i stor grad går opp i 8-gangen, et veldig standard grep som ender opp med at ting faller naturlig på linje. 

Border, og dette er jeg vant til at den gjør, legger seg på i høyden, så knappen vår som skal være 40px blir plutselig 42px. Dette vil potensielt skape en del følgefeil, særlig når den brukes flere ganger på samme skjerm, både alene og inni andre komponenter. 

Her vet jeg ikke hva som er den lureste metoden/strategien for å unngå at border dulter størrelser. (Jeg er også tilbøyelig til å slippe en første versjon uten fiks, men det må avklares ganske fort siden dette kommer til å gjelde mange komponenter).
created_at: 2025-02-07T09:49:58Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,388 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+export type FhiButtonProps = Pick<
+  FhiButton,
+  'color' | 'variant' | 'disabled' | 'size'
+>;
+
+/**
+ * Button component
+ *
+ * @tag fhi-button
+ *
+ * @slot contains the content of the button
+ *
+ */
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  /**
+   * Bestemmer fargen på knappen.
+   * @default 'accent'
+   */
+  @property({ type: String, reflect: true }) color:
+    | 'accent'
+    | 'neutral'
+    | 'danger' = 'accent';
+
+  /**
+   * Bestemmer varianten av knappen.
+   * @default 'strong'
+   */
+  @property({ type: String, reflect: true }) variant:
+    | 'strong'
+    | 'subtle'
+    | 'outlined'
+    | 'text' = 'strong';
+
+  /**
+   * Bestemmer størrelsen på knappen.
+   * @default 'medium'
+   */
+  @property({ type: String, reflect: true }) size?:
+    | 'large'
+    | 'medium'
+    | 'small' = 'medium';
+
+  /**
+   * Bestemmer om knappen er tilgjengelig.
+   * @deafult false
+   */
+  @property({ type: Boolean, reflect: true }) disabled = false;
+
+  render() {
+    return html`<button ?disabled=${this.disabled}>
+      <slot></slot>
+    </button>`;
+  }
+
+  static styles = css`
+    :host {
+      button {
+        border-radius: var(--fhi-border-radius-full);
+        border-style: inset;
+        border: 1px solid;
+        font-family: var(--fhi-font-family-roboto-flex);
+
+        display: inline-flex;
+        justify-content: center;
+        align-items: center;
+        transition-duration: var(--fhi-duration-slow);
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: trybern
body: `transition-timing-function: cubic-bezier(var(--fhi-ease-default));` må også slenges på.
created_at: 2025-02-07T09:58:00Z
author_association: CONTRIBUTOR
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.test.ts
user: login: dafn
body: A test making sure a child is displayed in the button could be nice as well
created_at: 2025-02-07T10:08:27Z
author_association: COLLABORATOR
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.test.ts
user: login: dafn
body: It might be usefull to add some tests that listen for click events and makes sure the fhi-button emits them when it should.
created_at: 2025-02-07T10:10:14Z
author_association: COLLABORATOR
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: dafn
body: `fhi-button` should also react to the keys `space` and `enter`. It should emit a `click` event on `enter -> keydown` and `space -> keyup`
created_at: 2025-02-07T10:11:58Z
author_association: COLLABORATOR
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: dafn
body: `fhi-button` should have support for the [type](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#type) attribute
created_at: 2025-02-07T10:13:13Z
author_association: COLLABORATOR
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: dafn
body: When `fhi-button` is `disabled` it should not have `pointer` as its cursor. It should instead have `default`
created_at: 2025-02-07T10:19:07Z
author_association: COLLABORATOR
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: dafn
body: The component should expose some component tokens. We should have a chat about it when you are available. Maybe @trybern wants to join as well.
created_at: 2025-02-07T10:20:07Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,388 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+export type FhiButtonProps = Pick<
+  FhiButton,
+  'color' | 'variant' | 'disabled' | 'size'
+>;
+
+/**
+ * Button component
+ *
+ * @tag fhi-button
+ *
+ * @slot contains the content of the button
+ *
+ */
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  /**
+   * Bestemmer fargen på knappen.
+   * @default 'accent'
+   */
+  @property({ type: String, reflect: true }) color:
+    | 'accent'
+    | 'neutral'
+    | 'danger' = 'accent';
+
+  /**
+   * Bestemmer varianten av knappen.
+   * @default 'strong'
+   */
+  @property({ type: String, reflect: true }) variant:
+    | 'strong'
+    | 'subtle'
+    | 'outlined'
+    | 'text' = 'strong';
+
+  /**
+   * Bestemmer størrelsen på knappen.
+   * @default 'medium'
+   */
+  @property({ type: String, reflect: true }) size?:
+    | 'large'
+    | 'medium'
+    | 'small' = 'medium';
+
+  /**
+   * Bestemmer om knappen er tilgjengelig.
+   * @deafult false
+   */
+  @property({ type: Boolean, reflect: true }) disabled = false;
+
+  render() {
+    return html`<button ?disabled=${this.disabled}>
+      <slot></slot>
+    </button>`;
+  }
+
+  static styles = css`
+    :host {
+      button {
+        border-radius: var(--fhi-border-radius-full);
+        border-style: inset;
+        border: 1px solid;
+        font-family: var(--fhi-font-family-roboto-flex);
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: trybern
body: Noe med gjengivelsen av fonten gjør at den virker tykkere enn det i Figma, selv om `font-weight` er helt riktig satt.

![image](https://github.com/user-attachments/assets/25966b80-9497-44a7-a219-58ac0d594e22)
Øverste linje er Roboto Flex (ingen endring), nederste er `system-ui` (for å sjekke om det var selve fonten). Knapp til høyre har `text-rendering: geometricPrecision;`.

Testet på litt forskjellige skjermer, men sliter med å få testet på Windows (PC-en min vil ikke koble seg på nett). Litt usikker hvordan vi skal angripe dette, men akkurat nå påvirker det lesbarheten ganske mye, slik jeg ser det. 
created_at: 2025-02-07T10:34:59Z
author_association: CONTRIBUTOR
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: proand
body: In OLD we use `cursor: not-allowed`... @trybern do you have any opinion?
created_at: 2025-02-07T11:01:22Z
author_association: CONTRIBUTOR
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: trybern
body: Currently reviewing myself, and were just about to comment on this myself. We should go for `cursor: not-allowed`, just to _mate inn med teskje_ that the button is in no way clickable. This should probably be documented as one of our standards, as it would apply to several components.
created_at: 2025-02-07T11:21:21Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,388 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+export type FhiButtonProps = Pick<
+  FhiButton,
+  'color' | 'variant' | 'disabled' | 'size'
+>;
+
+/**
+ * Button component
+ *
+ * @tag fhi-button
+ *
+ * @slot contains the content of the button
+ *
+ */
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  /**
+   * Bestemmer fargen på knappen.
+   * @default 'accent'
+   */
+  @property({ type: String, reflect: true }) color:
+    | 'accent'
+    | 'neutral'
+    | 'danger' = 'accent';
+
+  /**
+   * Bestemmer varianten av knappen.
+   * @default 'strong'
+   */
+  @property({ type: String, reflect: true }) variant:
+    | 'strong'
+    | 'subtle'
+    | 'outlined'
+    | 'text' = 'strong';
+
+  /**
+   * Bestemmer størrelsen på knappen.
+   * @default 'medium'
+   */
+  @property({ type: String, reflect: true }) size?:
+    | 'large'
+    | 'medium'
+    | 'small' = 'medium';
+
+  /**
+   * Bestemmer om knappen er tilgjengelig.
+   * @deafult false
+   */
+  @property({ type: Boolean, reflect: true }) disabled = false;
+
+  render() {
+    return html`<button ?disabled=${this.disabled}>
+      <slot></slot>
+    </button>`;
+  }
+
+  static styles = css`
+    :host {
+      button {
+        border-radius: var(--fhi-border-radius-full);
+        border-style: inset;
+        border: 1px solid;
+        font-family: var(--fhi-font-family-roboto-flex);
+
+        display: inline-flex;
+        justify-content: center;
+        align-items: center;
+        transition-duration: var(--fhi-duration-slow);
+
+        cursor: pointer;
+        &:disabled {
+          opacity: var(--fhi-opacity-disabled);
+        }
+      }
+    }
+
+    :host([size='large']) {
+      button {
+        font-size: var(--fhi-typography-label-large-font-size);
+        font-weight: var(--fhi-typography-label-large-font-weight);
+        line-height: var(--fhi-typography-label-large-line-height);
+        letter-spacing: var(--fhi-typography-label-large-letter-spacing);
+
+        padding-top: var(--fhi-spacing-200);
+        padding-right: var(--fhi-spacing-300);
+        padding-bottom: var(--fhi-spacing-200);
+        padding-left: var(--fhi-spacing-300);
+        gap: var(--fhi-spacing-100);
+      }
+    }
+
+    :host([size='medium']) {
+      button {
+        font-size: var(--fhi-typography-label-medium-font-size);
+        font-weight: var(--fhi-typography-label-medium-font-weight);
+        line-height: var(--fhi-typography-label-medium-line-height);
+        letter-spacing: var(--fhi-typography-label-medium-letter-spacing);
+
+        padding-top: var(--fhi-spacing-100);
+        padding-right: var(--fhi-spacing-200);
+        padding-bottom: var(--fhi-spacing-100);
+        padding-left: var(--fhi-spacing-200);
+        gap: var(--fhi-spacing-050);
+      }
+    }
+
+    :host([size='small']) {
+      button {
+        font-size: var(--fhi-tyopgraphy-label-medium-font-size);
+        font-weight: var(--fhi-typography-label-medium-font-weight);
+        line-height: var(--fhi-typography-label-medium-line-height);
+        letter-spacing: var(--fhi-typography-label-medium-letter-spacing);
+
+        padding-top: var(--fhi-spacing-050);
+        padding-right: var(--fhi-spacing-150);
+        padding-bottom: var(--fhi-spacing-050);
+        padding-left: var(--fhi-spacing-150);
+      }
+    }
+
+    :host([color='accent'][variant='strong']) {
+      button {
+        background-color: var(--fhi-color-accent-base);
+        border-color: var(--fhi-color-accent-base);
+        color: var(--fhi-color-accent-text-inverted);
+        &:hover {
+          background-color: var(--fhi-color-accent-base-hover);
+          border-color: var(--fhi-color-accent-base-hover);
+        }
+        &:active {
+          background-color: var(--fhi-color-accent-base-active);
+          border-color: var(--fhi-color-accent-base-active);
+        }
+        &:disabled {
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: trybern
body: Trenger vi spesifikke regler for `disabled` (annet enn den generelle _opacity_-en), når de er identiske med grunnstillen (aka. `normal`)?
created_at: 2025-02-07T11:35:22Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,388 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+export type FhiButtonProps = Pick<
+  FhiButton,
+  'color' | 'variant' | 'disabled' | 'size'
+>;
+
+/**
+ * Button component
+ *
+ * @tag fhi-button
+ *
+ * @slot contains the content of the button
+ *
+ */
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  /**
+   * Bestemmer fargen på knappen.
+   * @default 'accent'
+   */
+  @property({ type: String, reflect: true }) color:
+    | 'accent'
+    | 'neutral'
+    | 'danger' = 'accent';
+
+  /**
+   * Bestemmer varianten av knappen.
+   * @default 'strong'
+   */
+  @property({ type: String, reflect: true }) variant:
+    | 'strong'
+    | 'subtle'
+    | 'outlined'
+    | 'text' = 'strong';
+
+  /**
+   * Bestemmer størrelsen på knappen.
+   * @default 'medium'
+   */
+  @property({ type: String, reflect: true }) size?:
+    | 'large'
+    | 'medium'
+    | 'small' = 'medium';
+
+  /**
+   * Bestemmer om knappen er tilgjengelig.
+   * @deafult false
+   */
+  @property({ type: Boolean, reflect: true }) disabled = false;
+
+  render() {
+    return html`<button ?disabled=${this.disabled}>
+      <slot></slot>
+    </button>`;
+  }
+
+  static styles = css`
+    :host {
+      button {
+        border-radius: var(--fhi-border-radius-full);
+        border-style: inset;
+        border: 1px solid;
+        font-family: var(--fhi-font-family-roboto-flex);
+
+        display: inline-flex;
+        justify-content: center;
+        align-items: center;
+        transition-duration: var(--fhi-duration-slow);
+
+        cursor: pointer;
+        &:disabled {
+          opacity: var(--fhi-opacity-disabled);
+        }
+      }
+    }
+
+    :host([size='large']) {
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: trybern
body: `text`-variantene skal ha noe mindre padding på sidene, slik at de ikke sklir ut i rekker med flere knappetyper. Nå har de samme som resten. 
created_at: 2025-02-07T11:41:15Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,388 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+export type FhiButtonProps = Pick<
+  FhiButton,
+  'color' | 'variant' | 'disabled' | 'size'
+>;
+
+/**
+ * Button component
+ *
+ * @tag fhi-button
+ *
+ * @slot contains the content of the button
+ *
+ */
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  /**
+   * Bestemmer fargen på knappen.
+   * @default 'accent'
+   */
+  @property({ type: String, reflect: true }) color:
+    | 'accent'
+    | 'neutral'
+    | 'danger' = 'accent';
+
+  /**
+   * Bestemmer varianten av knappen.
+   * @default 'strong'
+   */
+  @property({ type: String, reflect: true }) variant:
+    | 'strong'
+    | 'subtle'
+    | 'outlined'
+    | 'text' = 'strong';
+
+  /**
+   * Bestemmer størrelsen på knappen.
+   * @default 'medium'
+   */
+  @property({ type: String, reflect: true }) size?:
+    | 'large'
+    | 'medium'
+    | 'small' = 'medium';
+
+  /**
+   * Bestemmer om knappen er tilgjengelig.
+   * @deafult false
+   */
+  @property({ type: Boolean, reflect: true }) disabled = false;
+
+  render() {
+    return html`<button ?disabled=${this.disabled}>
+      <slot></slot>
+    </button>`;
+  }
+
+  static styles = css`
+    :host {
+      button {
+        border-radius: var(--fhi-border-radius-full);
+        border-style: inset;
+        border: 1px solid;
+        font-family: var(--fhi-font-family-roboto-flex);
+
+        display: inline-flex;
+        justify-content: center;
+        align-items: center;
+        transition-duration: var(--fhi-duration-slow);
+
+        cursor: pointer;
+        &:disabled {
+          opacity: var(--fhi-opacity-disabled);
+        }
+      }
+    }
+
+    :host([size='large']) {
+      button {
+        font-size: var(--fhi-typography-label-large-font-size);
+        font-weight: var(--fhi-typography-label-large-font-weight);
+        line-height: var(--fhi-typography-label-large-line-height);
+        letter-spacing: var(--fhi-typography-label-large-letter-spacing);
+
+        padding-top: var(--fhi-spacing-200);
+        padding-right: var(--fhi-spacing-300);
+        padding-bottom: var(--fhi-spacing-200);
+        padding-left: var(--fhi-spacing-300);
+        gap: var(--fhi-spacing-100);
+      }
+    }
+
+    :host([size='medium']) {
+      button {
+        font-size: var(--fhi-typography-label-medium-font-size);
+        font-weight: var(--fhi-typography-label-medium-font-weight);
+        line-height: var(--fhi-typography-label-medium-line-height);
+        letter-spacing: var(--fhi-typography-label-medium-letter-spacing);
+
+        padding-top: var(--fhi-spacing-100);
+        padding-right: var(--fhi-spacing-200);
+        padding-bottom: var(--fhi-spacing-100);
+        padding-left: var(--fhi-spacing-200);
+        gap: var(--fhi-spacing-050);
+      }
+    }
+
+    :host([size='small']) {
+      button {
+        font-size: var(--fhi-tyopgraphy-label-medium-font-size);
+        font-weight: var(--fhi-typography-label-medium-font-weight);
+        line-height: var(--fhi-typography-label-medium-line-height);
+        letter-spacing: var(--fhi-typography-label-medium-letter-spacing);
+
+        padding-top: var(--fhi-spacing-050);
+        padding-right: var(--fhi-spacing-150);
+        padding-bottom: var(--fhi-spacing-050);
+        padding-left: var(--fhi-spacing-150);
+      }
+    }
+
+    :host([color='accent'][variant='strong']) {
+      button {
+        background-color: var(--fhi-color-accent-base);
+        border-color: var(--fhi-color-accent-base);
+        color: var(--fhi-color-accent-text-inverted);
+        &:hover {
+          background-color: var(--fhi-color-accent-base-hover);
+          border-color: var(--fhi-color-accent-base-hover);
+        }
+        &:active {
+          background-color: var(--fhi-color-accent-base-active);
+          border-color: var(--fhi-color-accent-base-active);
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: trybern
body: Av ren nysgjerrighet (og litt sett i sammenheng med neste kommentar om `disabled`): Hvorfor setter vi farge i stedet for `transparent`? Ville ikke det kunne kutte disse linjene på mange av variantene?
created_at: 2025-02-07T11:46:15Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,388 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+export type FhiButtonProps = Pick<
+  FhiButton,
+  'color' | 'variant' | 'disabled' | 'size'
+>;
+
+/**
+ * Button component
+ *
+ * @tag fhi-button
+ *
+ * @slot contains the content of the button
+ *
+ */
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  /**
+   * Bestemmer fargen på knappen.
+   * @default 'accent'
+   */
+  @property({ type: String, reflect: true }) color:
+    | 'accent'
+    | 'neutral'
+    | 'danger' = 'accent';
+
+  /**
+   * Bestemmer varianten av knappen.
+   * @default 'strong'
+   */
+  @property({ type: String, reflect: true }) variant:
+    | 'strong'
+    | 'subtle'
+    | 'outlined'
+    | 'text' = 'strong';
+
+  /**
+   * Bestemmer størrelsen på knappen.
+   * @default 'medium'
+   */
+  @property({ type: String, reflect: true }) size?:
+    | 'large'
+    | 'medium'
+    | 'small' = 'medium';
+
+  /**
+   * Bestemmer om knappen er tilgjengelig.
+   * @deafult false
+   */
+  @property({ type: Boolean, reflect: true }) disabled = false;
+
+  render() {
+    return html`<button ?disabled=${this.disabled}>
+      <slot></slot>
+    </button>`;
+  }
+
+  static styles = css`
+    :host {
+      button {
+        border-radius: var(--fhi-border-radius-full);
+        border-style: inset;
+        border: 1px solid;
+        font-family: var(--fhi-font-family-roboto-flex);
+
+        display: inline-flex;
+        justify-content: center;
+        align-items: center;
+        transition-duration: var(--fhi-duration-slow);
+
+        cursor: pointer;
+        &:disabled {
+          opacity: var(--fhi-opacity-disabled);
+        }
+      }
+    }
+
+    :host([size='large']) {
+      button {
+        font-size: var(--fhi-typography-label-large-font-size);
+        font-weight: var(--fhi-typography-label-large-font-weight);
+        line-height: var(--fhi-typography-label-large-line-height);
+        letter-spacing: var(--fhi-typography-label-large-letter-spacing);
+
+        padding-top: var(--fhi-spacing-200);
+        padding-right: var(--fhi-spacing-300);
+        padding-bottom: var(--fhi-spacing-200);
+        padding-left: var(--fhi-spacing-300);
+        gap: var(--fhi-spacing-100);
+      }
+    }
+
+    :host([size='medium']) {
+      button {
+        font-size: var(--fhi-typography-label-medium-font-size);
+        font-weight: var(--fhi-typography-label-medium-font-weight);
+        line-height: var(--fhi-typography-label-medium-line-height);
+        letter-spacing: var(--fhi-typography-label-medium-letter-spacing);
+
+        padding-top: var(--fhi-spacing-100);
+        padding-right: var(--fhi-spacing-200);
+        padding-bottom: var(--fhi-spacing-100);
+        padding-left: var(--fhi-spacing-200);
+        gap: var(--fhi-spacing-050);
+      }
+    }
+
+    :host([size='small']) {
+      button {
+        font-size: var(--fhi-tyopgraphy-label-medium-font-size);
+        font-weight: var(--fhi-typography-label-medium-font-weight);
+        line-height: var(--fhi-typography-label-medium-line-height);
+        letter-spacing: var(--fhi-typography-label-medium-letter-spacing);
+
+        padding-top: var(--fhi-spacing-050);
+        padding-right: var(--fhi-spacing-150);
+        padding-bottom: var(--fhi-spacing-050);
+        padding-left: var(--fhi-spacing-150);
+      }
+    }
+
+    :host([color='accent'][variant='strong']) {
+      button {
+        background-color: var(--fhi-color-accent-base);
+        border-color: var(--fhi-color-accent-base);
+        color: var(--fhi-color-accent-text-inverted);
+        &:hover {
+          background-color: var(--fhi-color-accent-base-hover);
+          border-color: var(--fhi-color-accent-base-hover);
+        }
+        &:active {
+          background-color: var(--fhi-color-accent-base-active);
+          border-color: var(--fhi-color-accent-base-active);
+        }
+        &:disabled {
+          background-color: var(--fhi-color-accent-base);
+          border-color: var(--fhi-color-accent-base);
+          color: var(--fhi-color-accent-text-inverted);
+        }
+      }
+    }
+
+    :host([color='accent'][variant='subtle']) {
+      button {
+        background-color: var(--fhi-color-accent-surface);
+        border-color: var(--fhi-color-accent-surface);
+        color: var(--fhi-color-accent-text-subtle);
+        &:hover {
+          background-color: var(--fhi-color-accent-surface-hover);
+          border-color: var(--fhi-color-accent-surface-hover);
+        }
+        &:active {
+          background-color: var(--fhi-color-accent-surface-active);
+          border-color: var(--fhi-color-accent-surface-active);
+        }
+        &:disabled {
+          background-color: var(--fhi-color-accent-surface);
+          border-color: var(--fhi-color-accent-surface);
+        }
+      }
+    }
+
+    :host([color='accent'][variant='outlined']) {
+      button {
+        border-color: var(--fhi-color-accent-border);
+        color: var(--fhi-color-accent-text-subtle);
+        background-color: transparent;
+        &:hover {
+          background-color: var(--fhi-color-accent-surface);
+          border-color: var(--fhi-color-accent-surface);
+        }
+        &:active {
+          background-color: var(--fhi-color-accent-surface-active);
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: trybern
body: ```suggestion
          background-color: var(--fhi-color-accent-surface-hover);
```
created_at: 2025-02-07T11:49:54Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,388 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+export type FhiButtonProps = Pick<
+  FhiButton,
+  'color' | 'variant' | 'disabled' | 'size'
+>;
+
+/**
+ * Button component
+ *
+ * @tag fhi-button
+ *
+ * @slot contains the content of the button
+ *
+ */
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  /**
+   * Bestemmer fargen på knappen.
+   * @default 'accent'
+   */
+  @property({ type: String, reflect: true }) color:
+    | 'accent'
+    | 'neutral'
+    | 'danger' = 'accent';
+
+  /**
+   * Bestemmer varianten av knappen.
+   * @default 'strong'
+   */
+  @property({ type: String, reflect: true }) variant:
+    | 'strong'
+    | 'subtle'
+    | 'outlined'
+    | 'text' = 'strong';
+
+  /**
+   * Bestemmer størrelsen på knappen.
+   * @default 'medium'
+   */
+  @property({ type: String, reflect: true }) size?:
+    | 'large'
+    | 'medium'
+    | 'small' = 'medium';
+
+  /**
+   * Bestemmer om knappen er tilgjengelig.
+   * @deafult false
+   */
+  @property({ type: Boolean, reflect: true }) disabled = false;
+
+  render() {
+    return html`<button ?disabled=${this.disabled}>
+      <slot></slot>
+    </button>`;
+  }
+
+  static styles = css`
+    :host {
+      button {
+        border-radius: var(--fhi-border-radius-full);
+        border-style: inset;
+        border: 1px solid;
+        font-family: var(--fhi-font-family-roboto-flex);
+
+        display: inline-flex;
+        justify-content: center;
+        align-items: center;
+        transition-duration: var(--fhi-duration-slow);
+
+        cursor: pointer;
+        &:disabled {
+          opacity: var(--fhi-opacity-disabled);
+        }
+      }
+    }
+
+    :host([size='large']) {
+      button {
+        font-size: var(--fhi-typography-label-large-font-size);
+        font-weight: var(--fhi-typography-label-large-font-weight);
+        line-height: var(--fhi-typography-label-large-line-height);
+        letter-spacing: var(--fhi-typography-label-large-letter-spacing);
+
+        padding-top: var(--fhi-spacing-200);
+        padding-right: var(--fhi-spacing-300);
+        padding-bottom: var(--fhi-spacing-200);
+        padding-left: var(--fhi-spacing-300);
+        gap: var(--fhi-spacing-100);
+      }
+    }
+
+    :host([size='medium']) {
+      button {
+        font-size: var(--fhi-typography-label-medium-font-size);
+        font-weight: var(--fhi-typography-label-medium-font-weight);
+        line-height: var(--fhi-typography-label-medium-line-height);
+        letter-spacing: var(--fhi-typography-label-medium-letter-spacing);
+
+        padding-top: var(--fhi-spacing-100);
+        padding-right: var(--fhi-spacing-200);
+        padding-bottom: var(--fhi-spacing-100);
+        padding-left: var(--fhi-spacing-200);
+        gap: var(--fhi-spacing-050);
+      }
+    }
+
+    :host([size='small']) {
+      button {
+        font-size: var(--fhi-tyopgraphy-label-medium-font-size);
+        font-weight: var(--fhi-typography-label-medium-font-weight);
+        line-height: var(--fhi-typography-label-medium-line-height);
+        letter-spacing: var(--fhi-typography-label-medium-letter-spacing);
+
+        padding-top: var(--fhi-spacing-050);
+        padding-right: var(--fhi-spacing-150);
+        padding-bottom: var(--fhi-spacing-050);
+        padding-left: var(--fhi-spacing-150);
+      }
+    }
+
+    :host([color='accent'][variant='strong']) {
+      button {
+        background-color: var(--fhi-color-accent-base);
+        border-color: var(--fhi-color-accent-base);
+        color: var(--fhi-color-accent-text-inverted);
+        &:hover {
+          background-color: var(--fhi-color-accent-base-hover);
+          border-color: var(--fhi-color-accent-base-hover);
+        }
+        &:active {
+          background-color: var(--fhi-color-accent-base-active);
+          border-color: var(--fhi-color-accent-base-active);
+        }
+        &:disabled {
+          background-color: var(--fhi-color-accent-base);
+          border-color: var(--fhi-color-accent-base);
+          color: var(--fhi-color-accent-text-inverted);
+        }
+      }
+    }
+
+    :host([color='accent'][variant='subtle']) {
+      button {
+        background-color: var(--fhi-color-accent-surface);
+        border-color: var(--fhi-color-accent-surface);
+        color: var(--fhi-color-accent-text-subtle);
+        &:hover {
+          background-color: var(--fhi-color-accent-surface-hover);
+          border-color: var(--fhi-color-accent-surface-hover);
+        }
+        &:active {
+          background-color: var(--fhi-color-accent-surface-active);
+          border-color: var(--fhi-color-accent-surface-active);
+        }
+        &:disabled {
+          background-color: var(--fhi-color-accent-surface);
+          border-color: var(--fhi-color-accent-surface);
+        }
+      }
+    }
+
+    :host([color='accent'][variant='outlined']) {
+      button {
+        border-color: var(--fhi-color-accent-border);
+        color: var(--fhi-color-accent-text-subtle);
+        background-color: transparent;
+        &:hover {
+          background-color: var(--fhi-color-accent-surface);
+          border-color: var(--fhi-color-accent-surface);
+        }
+        &:active {
+          background-color: var(--fhi-color-accent-surface-active);
+          border-color: var(--fhi-color-accent-surface-active);
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: trybern
body: ```suggestion
          border-color: var(--fhi-color-accent-surface-hover);
```
created_at: 2025-02-07T11:50:07Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,388 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+export type FhiButtonProps = Pick<
+  FhiButton,
+  'color' | 'variant' | 'disabled' | 'size'
+>;
+
+/**
+ * Button component
+ *
+ * @tag fhi-button
+ *
+ * @slot contains the content of the button
+ *
+ */
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  /**
+   * Bestemmer fargen på knappen.
+   * @default 'accent'
+   */
+  @property({ type: String, reflect: true }) color:
+    | 'accent'
+    | 'neutral'
+    | 'danger' = 'accent';
+
+  /**
+   * Bestemmer varianten av knappen.
+   * @default 'strong'
+   */
+  @property({ type: String, reflect: true }) variant:
+    | 'strong'
+    | 'subtle'
+    | 'outlined'
+    | 'text' = 'strong';
+
+  /**
+   * Bestemmer størrelsen på knappen.
+   * @default 'medium'
+   */
+  @property({ type: String, reflect: true }) size?:
+    | 'large'
+    | 'medium'
+    | 'small' = 'medium';
+
+  /**
+   * Bestemmer om knappen er tilgjengelig.
+   * @deafult false
+   */
+  @property({ type: Boolean, reflect: true }) disabled = false;
+
+  render() {
+    return html`<button ?disabled=${this.disabled}>
+      <slot></slot>
+    </button>`;
+  }
+
+  static styles = css`
+    :host {
+      button {
+        border-radius: var(--fhi-border-radius-full);
+        border-style: inset;
+        border: 1px solid;
+        font-family: var(--fhi-font-family-roboto-flex);
+
+        display: inline-flex;
+        justify-content: center;
+        align-items: center;
+        transition-duration: var(--fhi-duration-slow);
+
+        cursor: pointer;
+        &:disabled {
+          opacity: var(--fhi-opacity-disabled);
+        }
+      }
+    }
+
+    :host([size='large']) {
+      button {
+        font-size: var(--fhi-typography-label-large-font-size);
+        font-weight: var(--fhi-typography-label-large-font-weight);
+        line-height: var(--fhi-typography-label-large-line-height);
+        letter-spacing: var(--fhi-typography-label-large-letter-spacing);
+
+        padding-top: var(--fhi-spacing-200);
+        padding-right: var(--fhi-spacing-300);
+        padding-bottom: var(--fhi-spacing-200);
+        padding-left: var(--fhi-spacing-300);
+        gap: var(--fhi-spacing-100);
+      }
+    }
+
+    :host([size='medium']) {
+      button {
+        font-size: var(--fhi-typography-label-medium-font-size);
+        font-weight: var(--fhi-typography-label-medium-font-weight);
+        line-height: var(--fhi-typography-label-medium-line-height);
+        letter-spacing: var(--fhi-typography-label-medium-letter-spacing);
+
+        padding-top: var(--fhi-spacing-100);
+        padding-right: var(--fhi-spacing-200);
+        padding-bottom: var(--fhi-spacing-100);
+        padding-left: var(--fhi-spacing-200);
+        gap: var(--fhi-spacing-050);
+      }
+    }
+
+    :host([size='small']) {
+      button {
+        font-size: var(--fhi-tyopgraphy-label-medium-font-size);
+        font-weight: var(--fhi-typography-label-medium-font-weight);
+        line-height: var(--fhi-typography-label-medium-line-height);
+        letter-spacing: var(--fhi-typography-label-medium-letter-spacing);
+
+        padding-top: var(--fhi-spacing-050);
+        padding-right: var(--fhi-spacing-150);
+        padding-bottom: var(--fhi-spacing-050);
+        padding-left: var(--fhi-spacing-150);
+      }
+    }
+
+    :host([color='accent'][variant='strong']) {
+      button {
+        background-color: var(--fhi-color-accent-base);
+        border-color: var(--fhi-color-accent-base);
+        color: var(--fhi-color-accent-text-inverted);
+        &:hover {
+          background-color: var(--fhi-color-accent-base-hover);
+          border-color: var(--fhi-color-accent-base-hover);
+        }
+        &:active {
+          background-color: var(--fhi-color-accent-base-active);
+          border-color: var(--fhi-color-accent-base-active);
+        }
+        &:disabled {
+          background-color: var(--fhi-color-accent-base);
+          border-color: var(--fhi-color-accent-base);
+          color: var(--fhi-color-accent-text-inverted);
+        }
+      }
+    }
+
+    :host([color='accent'][variant='subtle']) {
+      button {
+        background-color: var(--fhi-color-accent-surface);
+        border-color: var(--fhi-color-accent-surface);
+        color: var(--fhi-color-accent-text-subtle);
+        &:hover {
+          background-color: var(--fhi-color-accent-surface-hover);
+          border-color: var(--fhi-color-accent-surface-hover);
+        }
+        &:active {
+          background-color: var(--fhi-color-accent-surface-active);
+          border-color: var(--fhi-color-accent-surface-active);
+        }
+        &:disabled {
+          background-color: var(--fhi-color-accent-surface);
+          border-color: var(--fhi-color-accent-surface);
+        }
+      }
+    }
+
+    :host([color='accent'][variant='outlined']) {
+      button {
+        border-color: var(--fhi-color-accent-border);
+        color: var(--fhi-color-accent-text-subtle);
+        background-color: transparent;
+        &:hover {
+          background-color: var(--fhi-color-accent-surface);
+          border-color: var(--fhi-color-accent-surface);
+        }
+        &:active {
+          background-color: var(--fhi-color-accent-surface-active);
+          border-color: var(--fhi-color-accent-surface-active);
+        }
+        &:disabled {
+          border-color: var(--fhi-color-accent-border);
+          background-color: transparent;
+        }
+      }
+    }
+
+    :host([color='accent'][variant='text']) {
+      button {
+        background-color: transparent;
+        border-color: transparent;
+        color: var(--fhi-color-accent-text-subtle);
+        &:hover {
+          background-color: var(--fhi-color-accent-surface);
+          border-color: var(--fhi-color-accent-surface);
+          color: var(--fhi-color-accent-text);
+        }
+        &:active {
+          background-color: var(--fhi-color-accent-surface-hover);
+          border-color: var(--fhi-color-accent-surface-hover);
+          color: var(--fhi-color-accent-text);
+        }
+        &:disabled {
+          background-color: transparent;
+          color: var(--fhi-color-accent-text-subtle);
+        }
+      }
+    }
+
+    :host([color='neutral'][variant='strong']) {
+      button {
+        background-color: var(--fhi-color-neutral-base);
+        border-color: var(--fhi-color-neutral-base);
+        color: var(--fhi-color-neutral-text-inverted);
+        &:hover {
+          background-color: var(--fhi-color-neutral-base-hover);
+          border-color: var(--fhi-color-neutral-base-hover);
+          color: var(--fhi-color-neutral-text-inverted);
+        }
+        &:active {
+          background-color: var(--fhi-color-neutral-base-active);
+          border-color: var(--fhi-color-neutral-base-active);
+          color: var(--fhi-color-neutral-text-inverted);
+        }
+        &:disabled {
+          background-color: var(--fhi-color-neutral-base);
+          border-color: var(--fhi-color-neutral-base);
+          color: var(--fhi-color-neutral-text-inverted);
+        }
+      }
+    }
+
+    :host([color='neutral'][variant='subtle']) {
+      button {
+        background-color: var(--fhi-color-neutral-surface);
+        border-color: var(--fhi-color-neutral-surface);
+        color: var(--fhi-color-neutral-text-subtle);
+        &:hover {
+          background-color: var(--fhi-color-neutral-surface-hover);
+          border-color: var(--fhi-color-neutral-surface-hover);
+          color: var(--fhi-color-neutral-text);
+        }
+        &:active {
+          background-color: var(--fhi-color-neutral-surface-active);
+          border-color: var(--fhi-color-neutral-surface-active);
+          color: var(--fhi-color-neutral-text);
+        }
+        &:disabled {
+          background-color: var(--fhi-color-neutral-surface);
+          border-color: var(--fhi-color-neutral-surface);
+          color: var(--fhi-color-neutral-text);
+        }
+      }
+    }
+
+    :host([color='neutral'][variant='outlined']) {
+      button {
+        border-color: var(--fhi-color-neutral-border);
+        color: var(--fhi-color-neutral-text-subtle);
+        background-color: transparent;
+        &:hover {
+          background-color: var(--fhi-color-neutral-surface);
+          border-color: var(--fhi-color-neutral-surface);
+          color: var(--fhi-color-neutral-text);
+        }
+        &:active {
+          background-color: var(--fhi-color-neutral-surface-hover);
+          border-color: var(--fhi-color-neutral-surface-hover);
+          color: var(--fhi-color-neutral-text);
+        }
+        &:disabled {
+          border-color: var(--fhi-color-neutral-border);
+          color: var(--fhi-color-neutral-text-subtle);
+          background-color: transparent;
+        }
+      }
+    }
+
+    :host([color='neutral'][variant='text']) {
+      button {
+        background-color: transparent;
+        border-color: transparent;
+        color: var(--fhi-color-neutral-text-subtle);
+        &:hover {
+          background-color: var(--fhi-color-neutral-surface);
+          border-color: var(--fhi-color-neutral-surface);
+          color: var(--fhi-color-neutral-text);
+        }
+        &:active {
+          background-color: var(--fhi-color-neutral-surface-hover);
+          border-color: var(--fhi-color-neutral-surface-hover);
+          color: var(--fhi-color-neutral-text);
+        }
+        &:disabled {
+          background-color: transparent;
+          border-color: transparent;
+          color: var(--fhi-color-neutral-text-subtle);
+        }
+      }
+    }
+
+    :host([color='danger'][variant='strong']) {
+      button {
+        background-color: var(--fhi-color-danger-base);
+        border-color: var(--fhi-color-danger-base);
+        color: var(--fhi-color-danger-text-inverted);
+        &:hover {
+          background-color: var(--fhi-color-danger-base-hover);
+          border-color: var(--fhi-color-danger-base-hover);
+        }
+        &:active {
+          background-color: var(--fhi-color-danger-base-active);
+          border-color: var(--fhi-color-danger-base-active);
+        }
+        &:disabled {
+          background-color: var(--fhi-color-danger-base);
+          border-color: var(--fhi-color-danger-base);
+        }
+      }
+    }
+
+    :host([color='danger'][variant='subtle']) {
+      button {
+        background-color: var(--fhi-color-danger-surface);
+        border-color: var(--fhi-color-danger-surface);
+        color: var(--fhi-color-danger-text-subtle);
+        &:hover {
+          background-color: var(--fhi-color-danger-surface-hover);
+          border-color: var(--fhi-color-danger-surface-hover);
+          color: var(--fhi-color-danger-text);
+        }
+        &:active {
+          background-color: var(--fhi-color-danger-surface-active);
+          border-color: var(--fhi-color-danger-surface-active);
+          color: var(--fhi-color-danger-text);
+        }
+        &:disabled {
+          background-color: var(--fhi-color-danger-surface);
+          border-color: var(--fhi-color-danger-surface);
+          color: var(--fhi-color-danger-text);
+        }
+      }
+    }
+
+    :host([color='danger'][variant='outlined']) {
+      button {
+        border-color: var(--fhi-color-danger-border);
+        color: var(--fhi-color-danger-text-subtle);
+        background-color: transparent;
+        &:hover {
+          background-color: var(--fhi-color-danger-surface);
+          border-color: var(--fhi-color-danger-surface);
+          color: var(--fhi-color-danger-text);
+        }
+        &:active {
+          background-color: var(--fhi-color-danger-surface-hover);
+          border-color: var(--fhi-color-danger-surface-hover);
+          color: var(--fhi-color-danger-text);
+        }
+        &:disabled {
+          border-color: var(--fhi-color-danger-border);
+          color: var(--fhi-color-danger-text);
+          background-color: transparent;
+        }
+      }
+    }
+    :host([color='danger'][variant='text']) {
+      button {
+        background-color: transparent;
+        border-color: transparent;
+        color: var(--fhi-color-danger-text-subtle);
+        &:hover {
+          background-color: var(--fhi-color-danger-surface);
+          border-color: var(--fhi-color-danger-surface);
+          color: var(--fhi-color-danger-text);
+        }
+        &:active {
+          background-color: var(--fhi-color-danger-surface-active);
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: trybern
body: ```suggestion
          background-color: var(--fhi-color-danger-surface-hover);
```
created_at: 2025-02-07T11:51:06Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,388 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+export type FhiButtonProps = Pick<
+  FhiButton,
+  'color' | 'variant' | 'disabled' | 'size'
+>;
+
+/**
+ * Button component
+ *
+ * @tag fhi-button
+ *
+ * @slot contains the content of the button
+ *
+ */
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  /**
+   * Bestemmer fargen på knappen.
+   * @default 'accent'
+   */
+  @property({ type: String, reflect: true }) color:
+    | 'accent'
+    | 'neutral'
+    | 'danger' = 'accent';
+
+  /**
+   * Bestemmer varianten av knappen.
+   * @default 'strong'
+   */
+  @property({ type: String, reflect: true }) variant:
+    | 'strong'
+    | 'subtle'
+    | 'outlined'
+    | 'text' = 'strong';
+
+  /**
+   * Bestemmer størrelsen på knappen.
+   * @default 'medium'
+   */
+  @property({ type: String, reflect: true }) size?:
+    | 'large'
+    | 'medium'
+    | 'small' = 'medium';
+
+  /**
+   * Bestemmer om knappen er tilgjengelig.
+   * @deafult false
+   */
+  @property({ type: Boolean, reflect: true }) disabled = false;
+
+  render() {
+    return html`<button ?disabled=${this.disabled}>
+      <slot></slot>
+    </button>`;
+  }
+
+  static styles = css`
+    :host {
+      button {
+        border-radius: var(--fhi-border-radius-full);
+        border-style: inset;
+        border: 1px solid;
+        font-family: var(--fhi-font-family-roboto-flex);
+
+        display: inline-flex;
+        justify-content: center;
+        align-items: center;
+        transition-duration: var(--fhi-duration-slow);
+
+        cursor: pointer;
+        &:disabled {
+          opacity: var(--fhi-opacity-disabled);
+        }
+      }
+    }
+
+    :host([size='large']) {
+      button {
+        font-size: var(--fhi-typography-label-large-font-size);
+        font-weight: var(--fhi-typography-label-large-font-weight);
+        line-height: var(--fhi-typography-label-large-line-height);
+        letter-spacing: var(--fhi-typography-label-large-letter-spacing);
+
+        padding-top: var(--fhi-spacing-200);
+        padding-right: var(--fhi-spacing-300);
+        padding-bottom: var(--fhi-spacing-200);
+        padding-left: var(--fhi-spacing-300);
+        gap: var(--fhi-spacing-100);
+      }
+    }
+
+    :host([size='medium']) {
+      button {
+        font-size: var(--fhi-typography-label-medium-font-size);
+        font-weight: var(--fhi-typography-label-medium-font-weight);
+        line-height: var(--fhi-typography-label-medium-line-height);
+        letter-spacing: var(--fhi-typography-label-medium-letter-spacing);
+
+        padding-top: var(--fhi-spacing-100);
+        padding-right: var(--fhi-spacing-200);
+        padding-bottom: var(--fhi-spacing-100);
+        padding-left: var(--fhi-spacing-200);
+        gap: var(--fhi-spacing-050);
+      }
+    }
+
+    :host([size='small']) {
+      button {
+        font-size: var(--fhi-tyopgraphy-label-medium-font-size);
+        font-weight: var(--fhi-typography-label-medium-font-weight);
+        line-height: var(--fhi-typography-label-medium-line-height);
+        letter-spacing: var(--fhi-typography-label-medium-letter-spacing);
+
+        padding-top: var(--fhi-spacing-050);
+        padding-right: var(--fhi-spacing-150);
+        padding-bottom: var(--fhi-spacing-050);
+        padding-left: var(--fhi-spacing-150);
+      }
+    }
+
+    :host([color='accent'][variant='strong']) {
+      button {
+        background-color: var(--fhi-color-accent-base);
+        border-color: var(--fhi-color-accent-base);
+        color: var(--fhi-color-accent-text-inverted);
+        &:hover {
+          background-color: var(--fhi-color-accent-base-hover);
+          border-color: var(--fhi-color-accent-base-hover);
+        }
+        &:active {
+          background-color: var(--fhi-color-accent-base-active);
+          border-color: var(--fhi-color-accent-base-active);
+        }
+        &:disabled {
+          background-color: var(--fhi-color-accent-base);
+          border-color: var(--fhi-color-accent-base);
+          color: var(--fhi-color-accent-text-inverted);
+        }
+      }
+    }
+
+    :host([color='accent'][variant='subtle']) {
+      button {
+        background-color: var(--fhi-color-accent-surface);
+        border-color: var(--fhi-color-accent-surface);
+        color: var(--fhi-color-accent-text-subtle);
+        &:hover {
+          background-color: var(--fhi-color-accent-surface-hover);
+          border-color: var(--fhi-color-accent-surface-hover);
+        }
+        &:active {
+          background-color: var(--fhi-color-accent-surface-active);
+          border-color: var(--fhi-color-accent-surface-active);
+        }
+        &:disabled {
+          background-color: var(--fhi-color-accent-surface);
+          border-color: var(--fhi-color-accent-surface);
+        }
+      }
+    }
+
+    :host([color='accent'][variant='outlined']) {
+      button {
+        border-color: var(--fhi-color-accent-border);
+        color: var(--fhi-color-accent-text-subtle);
+        background-color: transparent;
+        &:hover {
+          background-color: var(--fhi-color-accent-surface);
+          border-color: var(--fhi-color-accent-surface);
+        }
+        &:active {
+          background-color: var(--fhi-color-accent-surface-active);
+          border-color: var(--fhi-color-accent-surface-active);
+        }
+        &:disabled {
+          border-color: var(--fhi-color-accent-border);
+          background-color: transparent;
+        }
+      }
+    }
+
+    :host([color='accent'][variant='text']) {
+      button {
+        background-color: transparent;
+        border-color: transparent;
+        color: var(--fhi-color-accent-text-subtle);
+        &:hover {
+          background-color: var(--fhi-color-accent-surface);
+          border-color: var(--fhi-color-accent-surface);
+          color: var(--fhi-color-accent-text);
+        }
+        &:active {
+          background-color: var(--fhi-color-accent-surface-hover);
+          border-color: var(--fhi-color-accent-surface-hover);
+          color: var(--fhi-color-accent-text);
+        }
+        &:disabled {
+          background-color: transparent;
+          color: var(--fhi-color-accent-text-subtle);
+        }
+      }
+    }
+
+    :host([color='neutral'][variant='strong']) {
+      button {
+        background-color: var(--fhi-color-neutral-base);
+        border-color: var(--fhi-color-neutral-base);
+        color: var(--fhi-color-neutral-text-inverted);
+        &:hover {
+          background-color: var(--fhi-color-neutral-base-hover);
+          border-color: var(--fhi-color-neutral-base-hover);
+          color: var(--fhi-color-neutral-text-inverted);
+        }
+        &:active {
+          background-color: var(--fhi-color-neutral-base-active);
+          border-color: var(--fhi-color-neutral-base-active);
+          color: var(--fhi-color-neutral-text-inverted);
+        }
+        &:disabled {
+          background-color: var(--fhi-color-neutral-base);
+          border-color: var(--fhi-color-neutral-base);
+          color: var(--fhi-color-neutral-text-inverted);
+        }
+      }
+    }
+
+    :host([color='neutral'][variant='subtle']) {
+      button {
+        background-color: var(--fhi-color-neutral-surface);
+        border-color: var(--fhi-color-neutral-surface);
+        color: var(--fhi-color-neutral-text-subtle);
+        &:hover {
+          background-color: var(--fhi-color-neutral-surface-hover);
+          border-color: var(--fhi-color-neutral-surface-hover);
+          color: var(--fhi-color-neutral-text);
+        }
+        &:active {
+          background-color: var(--fhi-color-neutral-surface-active);
+          border-color: var(--fhi-color-neutral-surface-active);
+          color: var(--fhi-color-neutral-text);
+        }
+        &:disabled {
+          background-color: var(--fhi-color-neutral-surface);
+          border-color: var(--fhi-color-neutral-surface);
+          color: var(--fhi-color-neutral-text);
+        }
+      }
+    }
+
+    :host([color='neutral'][variant='outlined']) {
+      button {
+        border-color: var(--fhi-color-neutral-border);
+        color: var(--fhi-color-neutral-text-subtle);
+        background-color: transparent;
+        &:hover {
+          background-color: var(--fhi-color-neutral-surface);
+          border-color: var(--fhi-color-neutral-surface);
+          color: var(--fhi-color-neutral-text);
+        }
+        &:active {
+          background-color: var(--fhi-color-neutral-surface-hover);
+          border-color: var(--fhi-color-neutral-surface-hover);
+          color: var(--fhi-color-neutral-text);
+        }
+        &:disabled {
+          border-color: var(--fhi-color-neutral-border);
+          color: var(--fhi-color-neutral-text-subtle);
+          background-color: transparent;
+        }
+      }
+    }
+
+    :host([color='neutral'][variant='text']) {
+      button {
+        background-color: transparent;
+        border-color: transparent;
+        color: var(--fhi-color-neutral-text-subtle);
+        &:hover {
+          background-color: var(--fhi-color-neutral-surface);
+          border-color: var(--fhi-color-neutral-surface);
+          color: var(--fhi-color-neutral-text);
+        }
+        &:active {
+          background-color: var(--fhi-color-neutral-surface-hover);
+          border-color: var(--fhi-color-neutral-surface-hover);
+          color: var(--fhi-color-neutral-text);
+        }
+        &:disabled {
+          background-color: transparent;
+          border-color: transparent;
+          color: var(--fhi-color-neutral-text-subtle);
+        }
+      }
+    }
+
+    :host([color='danger'][variant='strong']) {
+      button {
+        background-color: var(--fhi-color-danger-base);
+        border-color: var(--fhi-color-danger-base);
+        color: var(--fhi-color-danger-text-inverted);
+        &:hover {
+          background-color: var(--fhi-color-danger-base-hover);
+          border-color: var(--fhi-color-danger-base-hover);
+        }
+        &:active {
+          background-color: var(--fhi-color-danger-base-active);
+          border-color: var(--fhi-color-danger-base-active);
+        }
+        &:disabled {
+          background-color: var(--fhi-color-danger-base);
+          border-color: var(--fhi-color-danger-base);
+        }
+      }
+    }
+
+    :host([color='danger'][variant='subtle']) {
+      button {
+        background-color: var(--fhi-color-danger-surface);
+        border-color: var(--fhi-color-danger-surface);
+        color: var(--fhi-color-danger-text-subtle);
+        &:hover {
+          background-color: var(--fhi-color-danger-surface-hover);
+          border-color: var(--fhi-color-danger-surface-hover);
+          color: var(--fhi-color-danger-text);
+        }
+        &:active {
+          background-color: var(--fhi-color-danger-surface-active);
+          border-color: var(--fhi-color-danger-surface-active);
+          color: var(--fhi-color-danger-text);
+        }
+        &:disabled {
+          background-color: var(--fhi-color-danger-surface);
+          border-color: var(--fhi-color-danger-surface);
+          color: var(--fhi-color-danger-text);
+        }
+      }
+    }
+
+    :host([color='danger'][variant='outlined']) {
+      button {
+        border-color: var(--fhi-color-danger-border);
+        color: var(--fhi-color-danger-text-subtle);
+        background-color: transparent;
+        &:hover {
+          background-color: var(--fhi-color-danger-surface);
+          border-color: var(--fhi-color-danger-surface);
+          color: var(--fhi-color-danger-text);
+        }
+        &:active {
+          background-color: var(--fhi-color-danger-surface-hover);
+          border-color: var(--fhi-color-danger-surface-hover);
+          color: var(--fhi-color-danger-text);
+        }
+        &:disabled {
+          border-color: var(--fhi-color-danger-border);
+          color: var(--fhi-color-danger-text);
+          background-color: transparent;
+        }
+      }
+    }
+    :host([color='danger'][variant='text']) {
+      button {
+        background-color: transparent;
+        border-color: transparent;
+        color: var(--fhi-color-danger-text-subtle);
+        &:hover {
+          background-color: var(--fhi-color-danger-surface);
+          border-color: var(--fhi-color-danger-surface);
+          color: var(--fhi-color-danger-text);
+        }
+        &:active {
+          background-color: var(--fhi-color-danger-surface-active);
+          border-color: var(--fhi-color-danger-surface-active);
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: trybern
body: ```suggestion
          border-color: var(--fhi-color-danger-surface-hover);
```
created_at: 2025-02-07T11:51:22Z
author_association: CONTRIBUTOR
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: dafn
body: Remember to export the `fhi-button` component in the `library.ts` file
created_at: 2025-02-11T09:48:48Z
author_association: COLLABORATOR
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: dafn
body: Remember to decare `fhi-button` as a an entry point in `vite.config.ts`. It should be declared in the `npm` case under `build.lib.entry`.
created_at: 2025-02-11T09:50:59Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,360 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+export type FhiButtonProps = Pick<
+  FhiButton,
+  'color' | 'variant' | 'disabled' | 'size'
+>;
+
+/**
+ * Button component
+ *
+ * @tag fhi-button
+ *
+ * @slot contains the content of the button
+ *
+ */
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  /**
+   * Bestemmer fargen på knappen.
+   * @default 'accent'
+   */
+  @property({ type: String, reflect: true }) color:
+    | 'accent'
+    | 'neutral'
+    | 'danger' = 'accent';
+
+  /**
+   * Bestemmer varianten av knappen.
+   * @default 'strong'
+   */
+  @property({ type: String, reflect: true }) variant:
+    | 'strong'
+    | 'subtle'
+    | 'outlined'
+    | 'text' = 'strong';
+
+  /**
+   * Bestemmer størrelsen på knappen.
+   * @default 'medium'
+   */
+  @property({ type: String, reflect: true }) size?:
+    | 'large'
+    | 'medium'
+    | 'small' = 'medium';
+
+  /**
+   * Bestemmer om knappen er tilgjengelig.
+   * @deafult false
+   */
+  @property({ type: Boolean, reflect: true }) disabled = false;
+
+  render() {
+    return html`<button ?disabled=${this.disabled}>
+      <slot></slot>
+    </button>`;
+  }
+
+  static styles = css`
+    :host {
+      button {
+        border-radius: var(--fhi-border-radius-full);
+        border: var(--fhi-border-width);
+        font-family: var(--fhi-font-family-roboto-flex);
+
+        display: inline-flex;
+        justify-content: center;
+        align-items: center;
+        transition-duration: var(--fhi-duration-quick);
+        transition-timing-function: cubic-bezier(var(--fhi-ease-default));
+
+        cursor: pointer;
+        &:disabled {
+          opacity: var(--fhi-opacity-disabled);
+          cursor: not-allowed;
+        }
+      }
+    }
+
+    :host([size='large']) button {
+      font-size: var(--fhi-typography-label-large-font-size);
+      font-weight: var(--fhi-typography-label-large-font-weight);
+      line-height: var(--fhi-typography-label-large-line-height);
+      letter-spacing: var(--fhi-typography-label-large-letter-spacing);
+
+      padding-top: var(--fhi-spacing-200);
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: dafn
body: top, right, bottom and left can be all set with a single `padding` declaration.
created_at: 2025-02-11T09:52:49Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,388 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+export type FhiButtonProps = Pick<
+  FhiButton,
+  'color' | 'variant' | 'disabled' | 'size'
+>;
+
+/**
+ * Button component
+ *
+ * @tag fhi-button
+ *
+ * @slot contains the content of the button
+ *
+ */
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  /**
+   * Bestemmer fargen på knappen.
+   * @default 'accent'
+   */
+  @property({ type: String, reflect: true }) color:
+    | 'accent'
+    | 'neutral'
+    | 'danger' = 'accent';
+
+  /**
+   * Bestemmer varianten av knappen.
+   * @default 'strong'
+   */
+  @property({ type: String, reflect: true }) variant:
+    | 'strong'
+    | 'subtle'
+    | 'outlined'
+    | 'text' = 'strong';
+
+  /**
+   * Bestemmer størrelsen på knappen.
+   * @default 'medium'
+   */
+  @property({ type: String, reflect: true }) size?:
+    | 'large'
+    | 'medium'
+    | 'small' = 'medium';
+
+  /**
+   * Bestemmer om knappen er tilgjengelig.
+   * @deafult false
+   */
+  @property({ type: Boolean, reflect: true }) disabled = false;
+
+  render() {
+    return html`<button ?disabled=${this.disabled}>
+      <slot></slot>
+    </button>`;
+  }
+
+  static styles = css`
+    :host {
+      button {
+        border-radius: var(--fhi-border-radius-full);
+        border-style: inset;
+        border: 1px solid;
+        font-family: var(--fhi-font-family-roboto-flex);
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: trybern
body: [Ble en egen sak med litt research.](https://github.com/FHIDev/Fhi.Designsystem.RnD/issues/78) Tenker vi lar eventuelle endringer håndteres separat, så denne kan vi markere som _resolved_.
created_at: 2025-02-12T06:43:41Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,63 @@
+import { FhiButton } from './fhi-button.ts';
+import * as FhiButtonStories from './fhi-button.stories.ts';
+import {
+  Meta,
+  Title,
+  Primary,
+  Canvas,
+  Story,
+  Controls,
+} from '@storybook/blocks';
+
+<Meta of={FhiButtonStories} />
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.docs.mdx
user: login: trybern
body: To litt generelle ting her, men som jeg har bitt meg merke i: 

1. Burde vi ikke vise de fleste property-ene utviklere kan justere på, slik at de (litt svart-på-hvitt) kan utforske og ev. bare kopiere koden (for eksempel for feilsøking)? Det vil jo etter hvert bli mange rader nedover i Storybook, men det kan være bedre å ha med én ting for mye enn én ting for lite.

2. Vi har jo noen definerte _defaults_, som nok ville vært deilig for utviklere å ikke skrive med mindre man trenger. Akkurat nå virker det som "alt" er påkrevd for å få knappen frem slik vi vil levere den, i stedet for å bare:

![Skjermbilde 2025-02-13 kl  11 19 34](https://github.com/user-attachments/assets/e5c340db-232f-46c1-99f5-8a51b7030bba)
created_at: 2025-02-13T10:33:06Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,366 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+import { ifDefined } from 'lit/directives/if-defined.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+export type FhiButtonProps = Pick<
+  FhiButton,
+  'color' | 'variant' | 'disabled' | 'size'
+>;
+
+/**
+ * Button component
+ *
+ * @tag fhi-button
+ *
+ * @slot contains the content of the button
+ *
+ */
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  /**
+   * Bestemmer fargen på knappen.
+   * @default 'accent'
+   */
+  @property({ type: String, reflect: true }) color:
+    | 'accent'
+    | 'neutral'
+    | 'danger' = 'accent';
+
+  /**
+   * Bestemmer varianten av knappen.
+   * @default 'strong'
+   */
+  @property({ type: String, reflect: true }) variant:
+    | 'strong'
+    | 'subtle'
+    | 'outlined'
+    | 'text' = 'strong';
+
+  /**
+   * Bestemmer størrelsen på knappen.
+   * @default 'medium'
+   */
+  @property({ type: String, reflect: true }) size?:
+    | 'large'
+    | 'medium'
+    | 'small' = 'medium';
+
+  /**
+   * Bestemmer om knappen er tilgjengelig.
+   * @deafult false
+   */
+  @property({ type: Boolean, reflect: true }) disabled = false;
+
+  @property({ type: String, reflect: true }) type?:
+    | 'button'
+    | 'submit'
+    | 'reset';
+
+  render() {
+    return html`<button ?disabled=${this.disabled} type=${ifDefined(this.type)}>
+      <slot></slot>
+    </button>`;
+  }
+
+  static styles = css`
+    :host {
+      button {
+        border-radius: var(--fhi-border-radius-full);
+        border: solid var(--fhi-border-width);
+        font-family: var(--fhi-font-family-roboto-flex);
+
+        display: inline-flex;
+        justify-content: center;
+        align-items: center;
+        transition-duration: var(--fhi-duration-quick);
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: dafn
body: `transition-duration` and `transition-timing-function` can be defined as a singe property; [transition](https://www.w3schools.com/cssref/css3_pr_transition.php)
created_at: 2025-02-21T09:20:39Z
author_association: COLLABORATOR
diff_hunk: @@ -66,16 +66,312 @@ export class FhiButton extends LitElement {
 
   static styles = css`
     :host {
+      --component-border-radius: var(--fhi-border-radius-full);
+      --component-font-family: var(--fhi-font-family-roboto-flex);
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: dafn
body: @trybern This is a good usecase for a semantic font-family token

ref: [90](https://github.com/FHIDev/Fhi.Designsystem/issues/90)
created_at: 2025-02-25T13:07:46Z
author_association: COLLABORATOR
diff_hunk: @@ -66,16 +66,312 @@ export class FhiButton extends LitElement {
 
   static styles = css`
     :host {
+      --component-border-radius: var(--fhi-border-radius-full);
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: dafn
body: using `--component` as a prefix here is redundant as the token is already scoped to a component
created_at: 2025-02-25T13:12:24Z
author_association: COLLABORATOR
diff_hunk: @@ -66,16 +66,312 @@ export class FhiButton extends LitElement {
 
   static styles = css`
     :host {
+      --component-border-radius: var(--fhi-border-radius-full);
+      --component-font-family: var(--fhi-font-family-roboto-flex);
+      --component-transition: var(--fhi-duration-quick)
+        cubic-bezier(var(--fhi-ease-default));
+
+      --component-label-large-letter-spacing: var(
+        --fhi-typography-label-large-letter-spacing
+      );
+      --component-label-medium-letter-spacing: var(
+        --fhi-typography-label-medium-letter-spacing
+      );
+      --component-label-small-letter-spacing: var(
+        --fhi-typography-label-small-letter-spacing
+      );
+      --component-label-large-line-height: var(
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: dafn
body: consider using the same grouping prefixes as the sematic tokens. It may make it easier to navigate the tokens. e.g `--typography-label-large-line-height`
created_at: 2025-02-25T13:16:01Z
author_association: COLLABORATOR
path: packages/fhi-designsystem/index.html
user: login: dafn
body: This file should not be comitted
created_at: 2025-02-26T13:47:42Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,388 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+export type FhiButtonProps = Pick<
+  FhiButton,
+  'color' | 'variant' | 'disabled' | 'size'
+>;
+
+/**
+ * Button component
+ *
+ * @tag fhi-button
+ *
+ * @slot contains the content of the button
+ *
+ */
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  /**
+   * Bestemmer fargen på knappen.
+   * @default 'accent'
+   */
+  @property({ type: String, reflect: true }) color:
+    | 'accent'
+    | 'neutral'
+    | 'danger' = 'accent';
+
+  /**
+   * Bestemmer varianten av knappen.
+   * @default 'strong'
+   */
+  @property({ type: String, reflect: true }) variant:
+    | 'strong'
+    | 'subtle'
+    | 'outlined'
+    | 'text' = 'strong';
+
+  /**
+   * Bestemmer størrelsen på knappen.
+   * @default 'medium'
+   */
+  @property({ type: String, reflect: true }) size?:
+    | 'large'
+    | 'medium'
+    | 'small' = 'medium';
+
+  /**
+   * Bestemmer om knappen er tilgjengelig.
+   * @deafult false
+   */
+  @property({ type: Boolean, reflect: true }) disabled = false;
+
+  render() {
+    return html`<button ?disabled=${this.disabled}>
+      <slot></slot>
+    </button>`;
+  }
+
+  static styles = css`
+    :host {
+      button {
+        border-radius: var(--fhi-border-radius-full);
+        border-style: inset;
+        border: 1px solid;
+        font-family: var(--fhi-font-family-roboto-flex);
+
+        display: inline-flex;
+        justify-content: center;
+        align-items: center;
+        transition-duration: var(--fhi-duration-slow);
+
+        cursor: pointer;
+        &:disabled {
+          opacity: var(--fhi-opacity-disabled);
+        }
+      }
+    }
+
+    :host([size='large']) {
+      button {
+        font-size: var(--fhi-typography-label-large-font-size);
+        font-weight: var(--fhi-typography-label-large-font-weight);
+        line-height: var(--fhi-typography-label-large-line-height);
+        letter-spacing: var(--fhi-typography-label-large-letter-spacing);
+
+        padding-top: var(--fhi-spacing-200);
+        padding-right: var(--fhi-spacing-300);
+        padding-bottom: var(--fhi-spacing-200);
+        padding-left: var(--fhi-spacing-300);
+        gap: var(--fhi-spacing-100);
+      }
+    }
+
+    :host([size='medium']) {
+      button {
+        font-size: var(--fhi-typography-label-medium-font-size);
+        font-weight: var(--fhi-typography-label-medium-font-weight);
+        line-height: var(--fhi-typography-label-medium-line-height);
+        letter-spacing: var(--fhi-typography-label-medium-letter-spacing);
+
+        padding-top: var(--fhi-spacing-100);
+        padding-right: var(--fhi-spacing-200);
+        padding-bottom: var(--fhi-spacing-100);
+        padding-left: var(--fhi-spacing-200);
+        gap: var(--fhi-spacing-050);
+      }
+    }
+
+    :host([size='small']) {
+      button {
+        font-size: var(--fhi-tyopgraphy-label-medium-font-size);
+        font-weight: var(--fhi-typography-label-medium-font-weight);
+        line-height: var(--fhi-typography-label-medium-line-height);
+        letter-spacing: var(--fhi-typography-label-medium-letter-spacing);
+
+        padding-top: var(--fhi-spacing-050);
+        padding-right: var(--fhi-spacing-150);
+        padding-bottom: var(--fhi-spacing-050);
+        padding-left: var(--fhi-spacing-150);
+      }
+    }
+
+    :host([color='accent'][variant='strong']) {
+      button {
+        background-color: var(--fhi-color-accent-base);
+        border-color: var(--fhi-color-accent-base);
+        color: var(--fhi-color-accent-text-inverted);
+        &:hover {
+          background-color: var(--fhi-color-accent-base-hover);
+          border-color: var(--fhi-color-accent-base-hover);
+        }
+        &:active {
+          background-color: var(--fhi-color-accent-base-active);
+          border-color: var(--fhi-color-accent-base-active);
+        }
+        &:disabled {
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: Masuso
body: Hvis vi ikke har regler på disabled så vil stylingen reagere på hover og active selv om den er satt til disabled. 
created_at: 2025-02-27T10:35:47Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,711 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+import { ifDefined } from 'lit/directives/if-defined.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+export type FhiButtonProps = Pick<
+  FhiButton,
+  'color' | 'variant' | 'disabled' | 'size'
+>;
+
+/**
+ * Button component
+ *
+ * @tag fhi-button
+ *
+ * @slot contains the content of the button
+ *
+ */
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  /**
+   * Bestemmer fargen på knappen.
+   * @default 'accent'
+   */
+  @property({ type: String, reflect: true }) color:
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: dafn
body: in most cases attributes should be considered inputs from it owner, so properties only needs to be reflected if an internal change to the property can occure and if the reflected attribute may be useful for the consumer.

In this instance, the property does not need to be reflected

I dont think any of the buttons properties needs to be reflected.
created_at: 2025-03-06T09:14:58Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,388 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+export type FhiButtonProps = Pick<
+  FhiButton,
+  'color' | 'variant' | 'disabled' | 'size'
+>;
+
+/**
+ * Button component
+ *
+ * @tag fhi-button
+ *
+ * @slot contains the content of the button
+ *
+ */
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  /**
+   * Bestemmer fargen på knappen.
+   * @default 'accent'
+   */
+  @property({ type: String, reflect: true }) color:
+    | 'accent'
+    | 'neutral'
+    | 'danger' = 'accent';
+
+  /**
+   * Bestemmer varianten av knappen.
+   * @default 'strong'
+   */
+  @property({ type: String, reflect: true }) variant:
+    | 'strong'
+    | 'subtle'
+    | 'outlined'
+    | 'text' = 'strong';
+
+  /**
+   * Bestemmer størrelsen på knappen.
+   * @default 'medium'
+   */
+  @property({ type: String, reflect: true }) size?:
+    | 'large'
+    | 'medium'
+    | 'small' = 'medium';
+
+  /**
+   * Bestemmer om knappen er tilgjengelig.
+   * @deafult false
+   */
+  @property({ type: Boolean, reflect: true }) disabled = false;
+
+  render() {
+    return html`<button ?disabled=${this.disabled}>
+      <slot></slot>
+    </button>`;
+  }
+
+  static styles = css`
+    :host {
+      button {
+        border-radius: var(--fhi-border-radius-full);
+        border-style: inset;
+        border: 1px solid;
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: proand
body: ```css
--border-width: var(--fhi-border-width);

--dimension-padding-small: calc(var(--fhi-spacing-050) - var(--fhi-border-width)) var(--fhi-spacing-150);
--dimension-padding-medium: calc(var(--fhi-spacing-100) - var(--fhi-border-width)) var(--fhi-spacing-200);
--dimension-padding-large: calc(var(--fhi-spacing-200) - var(--fhi-border-width)) var(--fhi-spacing-300);
```
created_at: 2025-03-10T09:07:19Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,711 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+import { ifDefined } from 'lit/directives/if-defined.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+export type FhiButtonProps = Pick<
+  FhiButton,
+  'color' | 'variant' | 'disabled' | 'size'
+>;
+
+/**
+ * Button component
+ *
+ * @tag fhi-button
+ *
+ * @slot contains the content of the button
+ *
+ */
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  /**
+   * Bestemmer fargen på knappen.
+   * @default 'accent'
+   */
+  @property({ type: String, reflect: true }) color:
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: Masuso
body: Den må reflektere fordi uten refleksjon blir ikke deafult verdien satt til en attribute, så styling vil ikke vises. 
created_at: 2025-03-10T09:14:40Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,659 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+import { ifDefined } from 'lit/directives/if-defined.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  @property({ type: String, reflect: true }) color:
+    | 'accent'
+    | 'neutral'
+    | 'danger' = 'accent';
+
+  @property({ type: String, reflect: true }) variant:
+    | 'strong'
+    | 'subtle'
+    | 'outlined'
+    | 'text' = 'strong';
+
+  @property({ type: String, reflect: true }) size?:
+    | 'large'
+    | 'medium'
+    | 'small' = 'medium';
+
+  @property({ type: Boolean, reflect: true }) disabled = false;
+
+  @property({ type: String }) type?: 'button' | 'submit' | 'reset';
+
+  private _formButton!: HTMLButtonElement;
+  private _form!: HTMLFormElement | null;
+
+  constructor() {
+    super();
+    this._stopClickLeak = this._stopClickLeak.bind(this);
+  }
+
+  override connectedCallback(): void {
+    if (!!super.connectedCallback) {
+      super.connectedCallback();
+    }
+
+    this._form = this.closest('form');
+  }
+
+  protected override firstUpdated(): void {
+    this._formButton = document.createElement('button');
+    this._formButton.addEventListener('click', this._stopClickLeak);
+    this.addEventListener('click', this._handleClick);
+  }
+
+  private _handleClick(event: MouseEvent): void {
+    if (
+      (this.type === 'submit' || this.type === 'reset') &&
+      this._form &&
+      !event.defaultPrevented
+    ) {
+      this._formButton.type = this.type;
+      this._form?.appendChild(this._formButton);
+      this._formButton.click();
+      this._form?.removeChild(this._formButton);
+    }
+  }
+
+  private _stopClickLeak(event: MouseEvent): void {
+    if (event.target === this._formButton) {
+      event.stopImmediatePropagation();
+    }
+  }
+
+  render() {
+    return html`<button ?disabled=${this.disabled} type=${ifDefined(this.type)}>
+      <slot></slot>
+    </button>`;
+  }
+
+  static styles = css`
+    :host {
+      --border-radius: var(--fhi-border-radius-full);
+      --typography-font-family: var(--fhi-font-family-roboto-flex);
+      --transition: var(--fhi-duration-quick)
+        cubic-bezier(var(--fhi-ease-default));
+
+      --opacity-disabled: var(--fhi-opacity-disabled);
+
+      --typography-label-font-size-large: var(
+        --fhi-typography-label-large-font-size
+      );
+      --typography-label-font-size-medium: var(
+        --fhi-typography-label-medium-font-size
+      );
+      --typography-label-font-size-small: var(
+        --fhi-typography-label-small-font-size
+      );
+      --typography-label-font-weight-large: var(
+        --fhi-typography-label-font-weight-large
+      );
+      --typography-label-font-weight-medium: var(
+        --fhi-typography-label-medium-font-weight
+      );
+      --typography-label-font-weight-small: var(
+        --fhi-typography-label-small-font-weight
+      );
+      --typography-label-line-height-large: var();
+
+      --typography-label-letter-spacing-large: var(
+        --fhi-typography-label-large-letter-spacing
+      );
+      --typography-label-letter-spacing-medium: var(
+        --fhi-typography-label-medium-letter-spacing
+      );
+      --typography-label-letter-spacing-small: var(
+        --fhi-typography-label-small-letter-spacing
+      );
+      --typography-label-line-height-large: var(
+        --fhi-typography-label-large-line-height
+      );
+      --typography-label-line-height-medium: var(
+        --fhi-typography-label-medium-line-height
+      );
+      --typography-label-line-height-small: var(
+        --fhi-typography-label-medium-line-height
+      );
+
+      --dimension-gap-large: var(--fhi-spacing-100);
+      --dimension-gap-medium: var(--fhi-spacing-050);
+      --dimension-gap-small: var(--fhi-spacing-0);
+
+      --border-width: var(--fhi-border-width);
+
+      --dimension-padding-small: calc(
+          var(--fhi-spacing-050) - var(--fhi-border-width)
+        )
+        var(--fhi-spacing-150);
+      --dimension-padding-medium: calc(
+          var(--fhi-spacing-100) - var(--fhi-border-width)
+        )
+        var(--fhi-spacing-200);
+      --dimension-padding-large: calc(
+          var(--fhi-spacing-200) - var(--fhi-border-width)
+        )
+        var(--fhi-spacing-300);
+      --color-accent-strong-background: var(--fhi-color-accent-base);
+      --color-accent-strong-border: var(--fhi-color-accent-base);
+      --color-accent-strong: var(--fhi-color-accent-text-inverted);
+      --color-accent-strong-background-hover: var(
+        --fhi-color-accent-base-hover
+      );
+      --color-accent-strong-border-hover: var(--fhi-color-accent-base-hover);
+      --color-accent-strong-hover: var(--fhi-color-accent-text-inverted);
+      --color-accent-strong-background-active: var(
+        --fhi-color-accent-base-active
+      );
+      --color-accent-strong-border-active: var(--fhi-color-accent-base-hover);
+      --color-accent-strong-active: var(--fhi-color-accent-text-inverted);
+      --color-accent-strong-background-disabled: var(--fhi-color-accent-base);
+      --color-accent-strong-border-disabled: var(--fhi-color-accent-base);
+      --color-accent-strong-disabled: var(--fhi-color-accent-text-inverted);
+
+      --color-accent-subtle-background: var(--fhi-color-accent-surface);
+      --color-accent-subtle-border: var(--fhi-color-accent-surface);
+      --color-accent-subtle: var(--fhi-color-accent-text-subtle);
+      --color-accent-subtle-background-hover: var(
+        --fhi-color-accent-surface-hover
+      );
+      --color-accent-subtle-border-hover: var(--fhi-color-accent-surface-hover);
+      --color-accent-subtle-hover: var(--fhi-color-accent-text);
+      --color-accent-subtle-background-active: var(
+        --fhi-color-accent-surface-active
+      );
+      --color-accent-subtle-border-active: var(
+        --fhi-color-accent-surface-active
+      );
+      --color-accent-subtle-active: var(--fhi-color-accent-text);
+      --color-accent-subtle-background-disabled: var(
+        --fhi-color-accent-surface
+      );
+      --color-accent-subtle-border-disabled: var(--fhi-color-accent-surface);
+      --color-accent-subtle-disabled: var(--fhi-color-accent-text-subtle);
+
+      --color-accent-outlined-background: transparent;
+      --color-accent-outlined-border: var(--fhi-color-accent-border);
+      --color-accent-outlined: var(--fhi-color-accent-text-subtle);
+      --color-accent-outlined-background-hover: var(--fhi-color-accent-surface);
+      --color-accent-outlined-border-hover: var(--fhi-color-accent-surface);
+      --color-accent-outlined-hover: var(--fhi-color-accent-text);
+      --color-accent-outlined-background-active: var(
+        --fhi-color-accent-surface-hover
+      );
+      --color-accent-outlined-border-active: var(
+        --fhi-color-accent-surface-hover
+      );
+      --color-accent-outlined-active: var(--fhi-color-accent-text);
+      --color-accent-outlined-background-disabled: transparent;
+      --color-accent-outlined-border-disabled: var(--fhi-color-surface-base);
+      --color-accent-outlined-disabled: var(--fhi-color-accent-text-subtle);
+
+      --color-accent-text-background: transparent;
+      --color-accent-text-border: transparent;
+      --color-accent-text: var(--fhi-color-accent-text-subtle);
+      --color-accent-text-background-hover: var(--fhi-color-accent-surface);
+      --color-accent-text-border-hover: var(--fhi-color-accent-surface);
+      --color-accent-text-hover: var(--fhi-color-accent-text);
+      --color-accent-text-background-active: var(
+        --fhi-color-accent-surface-hover
+      );
+      --color-accent-text-border-active: var(--fhi-color-accent-surface-hover);
+      --color-accent-text-active: var(--fhi-color-accent-text);
+      --color-accent-text-background-disabled: transparent;
+      --color-accent-text-border-disabled: transparent;
+      --color-accent-text-disabled: var(--fhi-color-accent-text);
+
+      --color-neutral-strong-background: var(--fhi-color-neutral-base);
+      --color-neutral-strong-border: var(--fhi-color-neutral-base);
+      --color-neutral-strong: var(--fhi-color-neutral-text-inverted);
+      --color-neutral-strong-background-hover: var(
+        --fhi-color-neutral-base-hover
+      );
+      --color-neutral-strong-border-hover: var(--fhi-color-neutral-base-hover);
+      --color-neutral-strong-hover: var(--fhi-color-neutral-text-inverted);
+      --color-neutral-strong-background-active: var(
+        --fhi-color-neutral-base-active
+      );
+      --color-neutral-strong-border-active: var(--fhi-color-neutral-base-hover);
+      --color-neutral-strong-active: var(--fhi-color-neutral-text-inverted);
+      --color-neutral-strong-background-disabled: var(--fhi-color-neutral-base);
+      --color-neutral-strong-border-disabled: var(--fhi-color-neutral-base);
+      --color-neutral-strong-disabled: var(--fhi-color-neutral-text-inverted);
+
+      --color-neutral-subtle-background: var(--fhi-color-neutral-surface);
+      --color-neutral-subtle-border: var(--fhi-color-neutral-surface);
+      --color-neutral-subtle: var(--fhi-color-neutral-text-subtle);
+      --color-neutral-subtle-background-hover: var(
+        --fhi-color-neutral-surface-hover
+      );
+      --color-neutral-subtle-border-hover: var(
+        --fhi-color-neutral-surface-hover
+      );
+      --color-neutral-subtle-hover: var(--fhi-color-neutral-text);
+      --color-neutral-subtle-background-active: var(
+        --fhi-color-neutral-surface-active
+      );
+      --color-neutral-subtle-border-active: var(
+        --fhi-color-neutral-surface-active
+      );
+      --color-neutral-subtle-active: var(--fhi-color-neutral-text);
+      --color-neutral-subtle-background-disabled: var(
+        --fhi-color-neutral-surface
+      );
+      --color-neutral-subtle-border-disabled: var(--fhi-color-neutral-surface);
+      --color-neutral-subtle-disabled: var(--fhi-color-neutral-text);
+
+      --color-neutral-outlined-background: transparent;
+      --color-neutral-outlined-border: var(--fhi-color-neutral-border);
+      --color-neutral-outlined: var(--fhi-color-neutral-text-subtle);
+      --color-neutral-outlined-background-hover: var(
+        --fhi-color-neutral-surface
+      );
+      --color-neutral-outlined-border-hover: var(--fhi-color-neutral-surface);
+      --color-neutral-outlined-hover: var(--fhi-color-neutral-text);
+      --color-neutral-outlined-background-active: var(
+        --fhi-color-neutral-surface-hover
+      );
+      --color-neutral-outlined-border-active: var(
+        --fhi-color-neutral-surface-hover
+      );
+      --color-neutral-outlined-active: var(--fhi-color-neutral-text);
+      --color-neutral-outlined-background-disabled: transparent;
+      --color-neutral-outlined-border-disabled: var(--fhi-color-surface-base);
+      --color-neutral-outlined-disabled: var(--fhi-color-neutral-text-subtle);
+
+      --color-neutral-text-background: transparent;
+      --color-neutral-text-border: transparent;
+      --color-neutral-text: var(--fhi-color-neutral-text-subtle);
+      --color-neutral-text-background-hover: var(--fhi-color-neutral-surface);
+      --color-neutral-text-border-hover: var(--fhi-color-neutral-surface);
+      --color-neutral-text-hover: var(--fhi-color-neutral-text);
+      --color-neutral-text-background-active: var(
+        --fhi-color-neutral-surface-hover
+      );
+      --color-neutral-text-border-active: var(
+        --fhi-color-neutral-surface-hover
+      );
+      --color-neutral-text-active: var(--fhi-color-neutral-text);
+      --color-neutral-text-background-disabled: transparent;
+      --color-neutral-text-border-disabled: transparent;
+      --color-neutral-text-disaabled: var(--fhi-color-neutral-text-subtle);
+
+      --color-danger-strong-background: var(--fhi-color-danger-base);
+      --color-danger-strong-border: var(--fhi-color-danger-base);
+      --color-danger-strong: var(--fhi-color-danger-text-inverted);
+      --color-danger-strong-background-hover: var(
+        --fhi-color-danger-base-hover
+      );
+      --color-danger-strong-border-hover: var(--fhi-color-danger-base-hover);
+      --color-danger-strong-hover: var(--fhi-color-danger-text-inverted);
+      --color-danger-strong-background-active: var(
+        --fhi-color-danger-base-active
+      );
+      --color-danger-strong-border-active: var(--fhi-color-danger-base-hover);
+      --color-danger-strong-active: var(--fhi-color-danger-text-inverted);
+      --color-danger-strong-background-disabled: var(--fhi-color-danger-base);
+      --color-danger-strong-border-disabled: var(--fhi-color-danger-base);
+      --color-danger-strong-disabled: var(--fhi-color-danger-text-inverted);
+
+      --color-danger-subtle-background: var(--fhi-color-danger-surface);
+      --color-danger-subtle-border: var(--fhi-color-danger-surface);
+      --color-danger-subtle: var(--fhi-color-danger-text-subtle);
+      --color-danger-subtle-background-hover: var(
+        --fhi-color-danger-surface-hover
+      );
+      --color-danger-subtle-border-hover: var(--fhi-color-danger-surface-hover);
+      --color-danger-subtle-hover: var(--fhi-color-danger-text);
+      --color-danger-subtle-background-active: var(
+        --fhi-color-danger-surface-active
+      );
+      --color-danger-subtle-border-active: var(
+        --fhi-color-danger-surface-active
+      );
+      --color-danger-subtle-active: var(--fhi-color-danger-text);
+      --color-danger-subtle-background-disabled: var(
+        --fhi-color-danger-surface
+      );
+      --color-danger-subtle-border-disabled: var(--fhi-color-danger-surface);
+      --color-danger-subtle-disabled: var(--fhi-color-danger-text-subtle);
+
+      --color-danger-outlined-background-color: transparent;
+      --color-danger-outlined-border: var(--fhi-color-danger-border);
+      --color-danger-outlined: var(--fhi-color-danger-text-subtle);
+      --color-danger-outlined-background-hover: var(--fhi-color-danger-surface);
+      --color-danger-outlined-border-hover: var(--fhi-color-danger-surface);
+      --color-danger-outlined-hover: var(--fhi-color-danger-text);
+      --color-danger-outlined-background-active: var(
+        --fhi-color-danger-surface-hover
+      );
+      --color-danger-outlined-border-active: var(
+        --fhi-color-danger-surface-hover
+      );
+      --color-danger-outlined-active: var(--fhi-color-danger-text);
+      --color-danger-outlined-background-disabled: transparent;
+      --color-danger-outlined-border-disabled: var(--fhi-color-danger-border);
+      --color-danger-outlined-disabled: var(--fhi-color-danger-text-subtle);
+
+      --color-danger-text-background: transparent;
+      --color-danger-text-border: transparent;
+      --color-danger-text: var(--fhi-color-danger-text-subtle);
+      --color-danger-text-background-hover: var(--fhi-color-danger-surface);
+      --color-danger-text-border-hover: var(--fhi-color-danger-surface);
+      --color-danger-text-hover: var(--fhi-color-danger-text);
+      --color-danger-text-background-active: var(
+        --fhi-color-danger-surface-hover
+      );
+      --color-danger-text-border-active: var(--fhi-color-danger-surface-hover);
+      --color-danger-text-active: var(--fhi-color-danger-text);
+      --color-danger-text-background-disabled: transparent;
+      --color-danger-text-border-disabled: transparent;
+      --color-danger-text-disabled: var(--fhi-color-danger-text-subtle);
+
+      button {
+        border-radius: var(--border-radius);
+        border: solid var(--fhi-border-width);
+        font-family: var(--typography-font-family);
+
+        display: inline-flex;
+        justify-content: center;
+        align-items: center;
+
+        transition: var(--transition);
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: dafn
body: Im not sure if the transition works as intended. @trybern should also do a little test of the button to make sure it conforms with design. I'll deploy it to Storybook in test
created_at: 2025-03-12T14:27:35Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,659 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+import { ifDefined } from 'lit/directives/if-defined.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  @property({ type: String, reflect: true }) color:
+    | 'accent'
+    | 'neutral'
+    | 'danger' = 'accent';
+
+  @property({ type: String, reflect: true }) variant:
+    | 'strong'
+    | 'subtle'
+    | 'outlined'
+    | 'text' = 'strong';
+
+  @property({ type: String, reflect: true }) size?:
+    | 'large'
+    | 'medium'
+    | 'small' = 'medium';
+
+  @property({ type: Boolean, reflect: true }) disabled = false;
+
+  @property({ type: String }) type?: 'button' | 'submit' | 'reset';
+
+  private _formButton!: HTMLButtonElement;
+  private _form!: HTMLFormElement | null;
+
+  constructor() {
+    super();
+    this._stopClickLeak = this._stopClickLeak.bind(this);
+  }
+
+  override connectedCallback(): void {
+    if (!!super.connectedCallback) {
+      super.connectedCallback();
+    }
+
+    this._form = this.closest('form');
+  }
+
+  protected override firstUpdated(): void {
+    this._formButton = document.createElement('button');
+    this._formButton.addEventListener('click', this._stopClickLeak);
+    this.addEventListener('click', this._handleClick);
+  }
+
+  private _handleClick(event: MouseEvent): void {
+    if (
+      (this.type === 'submit' || this.type === 'reset') &&
+      this._form &&
+      !event.defaultPrevented
+    ) {
+      this._formButton.type = this.type;
+      this._form?.appendChild(this._formButton);
+      this._formButton.click();
+      this._form?.removeChild(this._formButton);
+    }
+  }
+
+  private _stopClickLeak(event: MouseEvent): void {
+    if (event.target === this._formButton) {
+      event.stopImmediatePropagation();
+    }
+  }
+
+  render() {
+    return html`<button ?disabled=${this.disabled} type=${ifDefined(this.type)}>
+      <slot></slot>
+    </button>`;
+  }
+
+  static styles = css`
+    :host {
+      --border-radius: var(--fhi-border-radius-full);
+      --typography-font-family: var(--fhi-font-family-roboto-flex);
+      --transition: var(--fhi-duration-quick)
+        cubic-bezier(var(--fhi-ease-default));
+
+      --opacity-disabled: var(--fhi-opacity-disabled);
+
+      --typography-label-font-size-large: var(
+        --fhi-typography-label-large-font-size
+      );
+      --typography-label-font-size-medium: var(
+        --fhi-typography-label-medium-font-size
+      );
+      --typography-label-font-size-small: var(
+        --fhi-typography-label-small-font-size
+      );
+      --typography-label-font-weight-large: var(
+        --fhi-typography-label-font-weight-large
+      );
+      --typography-label-font-weight-medium: var(
+        --fhi-typography-label-medium-font-weight
+      );
+      --typography-label-font-weight-small: var(
+        --fhi-typography-label-small-font-weight
+      );
+      --typography-label-line-height-large: var();
+
+      --typography-label-letter-spacing-large: var(
+        --fhi-typography-label-large-letter-spacing
+      );
+      --typography-label-letter-spacing-medium: var(
+        --fhi-typography-label-medium-letter-spacing
+      );
+      --typography-label-letter-spacing-small: var(
+        --fhi-typography-label-small-letter-spacing
+      );
+      --typography-label-line-height-large: var(
+        --fhi-typography-label-large-line-height
+      );
+      --typography-label-line-height-medium: var(
+        --fhi-typography-label-medium-line-height
+      );
+      --typography-label-line-height-small: var(
+        --fhi-typography-label-medium-line-height
+      );
+
+      --dimension-gap-large: var(--fhi-spacing-100);
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: dafn
body: When I disable the gap property nothing seems to change. Is this "gap" needed?
created_at: 2025-03-12T14:30:25Z
author_association: COLLABORATOR
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: dafn
body: Some tokens are not properly mapped. This is one example, but I think there are at least three of them.

<img width="639" alt="Skjermbilde 2025-03-12 kl  15 28 40" src="https://github.com/user-attachments/assets/c5a8a4a2-0a22-4d90-a931-a8e1d85fc216" />

created_at: 2025-03-12T14:35:29Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,659 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+import { ifDefined } from 'lit/directives/if-defined.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  @property({ type: String, reflect: true }) color:
+    | 'accent'
+    | 'neutral'
+    | 'danger' = 'accent';
+
+  @property({ type: String, reflect: true }) variant:
+    | 'strong'
+    | 'subtle'
+    | 'outlined'
+    | 'text' = 'strong';
+
+  @property({ type: String, reflect: true }) size?:
+    | 'large'
+    | 'medium'
+    | 'small' = 'medium';
+
+  @property({ type: Boolean, reflect: true }) disabled = false;
+
+  @property({ type: String }) type?: 'button' | 'submit' | 'reset';
+
+  private _formButton!: HTMLButtonElement;
+  private _form!: HTMLFormElement | null;
+
+  constructor() {
+    super();
+    this._stopClickLeak = this._stopClickLeak.bind(this);
+  }
+
+  override connectedCallback(): void {
+    if (!!super.connectedCallback) {
+      super.connectedCallback();
+    }
+
+    this._form = this.closest('form');
+  }
+
+  protected override firstUpdated(): void {
+    this._formButton = document.createElement('button');
+    this._formButton.addEventListener('click', this._stopClickLeak);
+    this.addEventListener('click', this._handleClick);
+  }
+
+  private _handleClick(event: MouseEvent): void {
+    if (
+      (this.type === 'submit' || this.type === 'reset') &&
+      this._form &&
+      !event.defaultPrevented
+    ) {
+      this._formButton.type = this.type;
+      this._form?.appendChild(this._formButton);
+      this._formButton.click();
+      this._form?.removeChild(this._formButton);
+    }
+  }
+
+  private _stopClickLeak(event: MouseEvent): void {
+    if (event.target === this._formButton) {
+      event.stopImmediatePropagation();
+    }
+  }
+
+  render() {
+    return html`<button ?disabled=${this.disabled} type=${ifDefined(this.type)}>
+      <slot></slot>
+    </button>`;
+  }
+
+  static styles = css`
+    :host {
+      --border-radius: var(--fhi-border-radius-full);
+      --typography-font-family: var(--fhi-font-family-roboto-flex);
+      --transition: var(--fhi-duration-quick)
+        cubic-bezier(var(--fhi-ease-default));
+
+      --opacity-disabled: var(--fhi-opacity-disabled);
+
+      --typography-label-font-size-large: var(
+        --fhi-typography-label-large-font-size
+      );
+      --typography-label-font-size-medium: var(
+        --fhi-typography-label-medium-font-size
+      );
+      --typography-label-font-size-small: var(
+        --fhi-typography-label-small-font-size
+      );
+      --typography-label-font-weight-large: var(
+        --fhi-typography-label-font-weight-large
+      );
+      --typography-label-font-weight-medium: var(
+        --fhi-typography-label-medium-font-weight
+      );
+      --typography-label-font-weight-small: var(
+        --fhi-typography-label-small-font-weight
+      );
+      --typography-label-line-height-large: var();
+
+      --typography-label-letter-spacing-large: var(
+        --fhi-typography-label-large-letter-spacing
+      );
+      --typography-label-letter-spacing-medium: var(
+        --fhi-typography-label-medium-letter-spacing
+      );
+      --typography-label-letter-spacing-small: var(
+        --fhi-typography-label-small-letter-spacing
+      );
+      --typography-label-line-height-large: var(
+        --fhi-typography-label-large-line-height
+      );
+      --typography-label-line-height-medium: var(
+        --fhi-typography-label-medium-line-height
+      );
+      --typography-label-line-height-small: var(
+        --fhi-typography-label-medium-line-height
+      );
+
+      --dimension-gap-large: var(--fhi-spacing-100);
+      --dimension-gap-medium: var(--fhi-spacing-050);
+      --dimension-gap-small: var(--fhi-spacing-0);
+
+      --border-width: var(--fhi-border-width);
+
+      --dimension-padding-small: calc(
+          var(--fhi-spacing-050) - var(--fhi-border-width)
+        )
+        var(--fhi-spacing-150);
+      --dimension-padding-medium: calc(
+          var(--fhi-spacing-100) - var(--fhi-border-width)
+        )
+        var(--fhi-spacing-200);
+      --dimension-padding-large: calc(
+          var(--fhi-spacing-200) - var(--fhi-border-width)
+        )
+        var(--fhi-spacing-300);
+      --color-accent-strong-background: var(--fhi-color-accent-base);
+      --color-accent-strong-border: var(--fhi-color-accent-base);
+      --color-accent-strong: var(--fhi-color-accent-text-inverted);
+      --color-accent-strong-background-hover: var(
+        --fhi-color-accent-base-hover
+      );
+      --color-accent-strong-border-hover: var(--fhi-color-accent-base-hover);
+      --color-accent-strong-hover: var(--fhi-color-accent-text-inverted);
+      --color-accent-strong-background-active: var(
+        --fhi-color-accent-base-active
+      );
+      --color-accent-strong-border-active: var(--fhi-color-accent-base-hover);
+      --color-accent-strong-active: var(--fhi-color-accent-text-inverted);
+      --color-accent-strong-background-disabled: var(--fhi-color-accent-base);
+      --color-accent-strong-border-disabled: var(--fhi-color-accent-base);
+      --color-accent-strong-disabled: var(--fhi-color-accent-text-inverted);
+
+      --color-accent-subtle-background: var(--fhi-color-accent-surface);
+      --color-accent-subtle-border: var(--fhi-color-accent-surface);
+      --color-accent-subtle: var(--fhi-color-accent-text-subtle);
+      --color-accent-subtle-background-hover: var(
+        --fhi-color-accent-surface-hover
+      );
+      --color-accent-subtle-border-hover: var(--fhi-color-accent-surface-hover);
+      --color-accent-subtle-hover: var(--fhi-color-accent-text);
+      --color-accent-subtle-background-active: var(
+        --fhi-color-accent-surface-active
+      );
+      --color-accent-subtle-border-active: var(
+        --fhi-color-accent-surface-active
+      );
+      --color-accent-subtle-active: var(--fhi-color-accent-text);
+      --color-accent-subtle-background-disabled: var(
+        --fhi-color-accent-surface
+      );
+      --color-accent-subtle-border-disabled: var(--fhi-color-accent-surface);
+      --color-accent-subtle-disabled: var(--fhi-color-accent-text-subtle);
+
+      --color-accent-outlined-background: transparent;
+      --color-accent-outlined-border: var(--fhi-color-accent-border);
+      --color-accent-outlined: var(--fhi-color-accent-text-subtle);
+      --color-accent-outlined-background-hover: var(--fhi-color-accent-surface);
+      --color-accent-outlined-border-hover: var(--fhi-color-accent-surface);
+      --color-accent-outlined-hover: var(--fhi-color-accent-text);
+      --color-accent-outlined-background-active: var(
+        --fhi-color-accent-surface-hover
+      );
+      --color-accent-outlined-border-active: var(
+        --fhi-color-accent-surface-hover
+      );
+      --color-accent-outlined-active: var(--fhi-color-accent-text);
+      --color-accent-outlined-background-disabled: transparent;
+      --color-accent-outlined-border-disabled: var(--fhi-color-surface-base);
+      --color-accent-outlined-disabled: var(--fhi-color-accent-text-subtle);
+
+      --color-accent-text-background: transparent;
+      --color-accent-text-border: transparent;
+      --color-accent-text: var(--fhi-color-accent-text-subtle);
+      --color-accent-text-background-hover: var(--fhi-color-accent-surface);
+      --color-accent-text-border-hover: var(--fhi-color-accent-surface);
+      --color-accent-text-hover: var(--fhi-color-accent-text);
+      --color-accent-text-background-active: var(
+        --fhi-color-accent-surface-hover
+      );
+      --color-accent-text-border-active: var(--fhi-color-accent-surface-hover);
+      --color-accent-text-active: var(--fhi-color-accent-text);
+      --color-accent-text-background-disabled: transparent;
+      --color-accent-text-border-disabled: transparent;
+      --color-accent-text-disabled: var(--fhi-color-accent-text);
+
+      --color-neutral-strong-background: var(--fhi-color-neutral-base);
+      --color-neutral-strong-border: var(--fhi-color-neutral-base);
+      --color-neutral-strong: var(--fhi-color-neutral-text-inverted);
+      --color-neutral-strong-background-hover: var(
+        --fhi-color-neutral-base-hover
+      );
+      --color-neutral-strong-border-hover: var(--fhi-color-neutral-base-hover);
+      --color-neutral-strong-hover: var(--fhi-color-neutral-text-inverted);
+      --color-neutral-strong-background-active: var(
+        --fhi-color-neutral-base-active
+      );
+      --color-neutral-strong-border-active: var(--fhi-color-neutral-base-hover);
+      --color-neutral-strong-active: var(--fhi-color-neutral-text-inverted);
+      --color-neutral-strong-background-disabled: var(--fhi-color-neutral-base);
+      --color-neutral-strong-border-disabled: var(--fhi-color-neutral-base);
+      --color-neutral-strong-disabled: var(--fhi-color-neutral-text-inverted);
+
+      --color-neutral-subtle-background: var(--fhi-color-neutral-surface);
+      --color-neutral-subtle-border: var(--fhi-color-neutral-surface);
+      --color-neutral-subtle: var(--fhi-color-neutral-text-subtle);
+      --color-neutral-subtle-background-hover: var(
+        --fhi-color-neutral-surface-hover
+      );
+      --color-neutral-subtle-border-hover: var(
+        --fhi-color-neutral-surface-hover
+      );
+      --color-neutral-subtle-hover: var(--fhi-color-neutral-text);
+      --color-neutral-subtle-background-active: var(
+        --fhi-color-neutral-surface-active
+      );
+      --color-neutral-subtle-border-active: var(
+        --fhi-color-neutral-surface-active
+      );
+      --color-neutral-subtle-active: var(--fhi-color-neutral-text);
+      --color-neutral-subtle-background-disabled: var(
+        --fhi-color-neutral-surface
+      );
+      --color-neutral-subtle-border-disabled: var(--fhi-color-neutral-surface);
+      --color-neutral-subtle-disabled: var(--fhi-color-neutral-text);
+
+      --color-neutral-outlined-background: transparent;
+      --color-neutral-outlined-border: var(--fhi-color-neutral-border);
+      --color-neutral-outlined: var(--fhi-color-neutral-text-subtle);
+      --color-neutral-outlined-background-hover: var(
+        --fhi-color-neutral-surface
+      );
+      --color-neutral-outlined-border-hover: var(--fhi-color-neutral-surface);
+      --color-neutral-outlined-hover: var(--fhi-color-neutral-text);
+      --color-neutral-outlined-background-active: var(
+        --fhi-color-neutral-surface-hover
+      );
+      --color-neutral-outlined-border-active: var(
+        --fhi-color-neutral-surface-hover
+      );
+      --color-neutral-outlined-active: var(--fhi-color-neutral-text);
+      --color-neutral-outlined-background-disabled: transparent;
+      --color-neutral-outlined-border-disabled: var(--fhi-color-surface-base);
+      --color-neutral-outlined-disabled: var(--fhi-color-neutral-text-subtle);
+
+      --color-neutral-text-background: transparent;
+      --color-neutral-text-border: transparent;
+      --color-neutral-text: var(--fhi-color-neutral-text-subtle);
+      --color-neutral-text-background-hover: var(--fhi-color-neutral-surface);
+      --color-neutral-text-border-hover: var(--fhi-color-neutral-surface);
+      --color-neutral-text-hover: var(--fhi-color-neutral-text);
+      --color-neutral-text-background-active: var(
+        --fhi-color-neutral-surface-hover
+      );
+      --color-neutral-text-border-active: var(
+        --fhi-color-neutral-surface-hover
+      );
+      --color-neutral-text-active: var(--fhi-color-neutral-text);
+      --color-neutral-text-background-disabled: transparent;
+      --color-neutral-text-border-disabled: transparent;
+      --color-neutral-text-disaabled: var(--fhi-color-neutral-text-subtle);
+
+      --color-danger-strong-background: var(--fhi-color-danger-base);
+      --color-danger-strong-border: var(--fhi-color-danger-base);
+      --color-danger-strong: var(--fhi-color-danger-text-inverted);
+      --color-danger-strong-background-hover: var(
+        --fhi-color-danger-base-hover
+      );
+      --color-danger-strong-border-hover: var(--fhi-color-danger-base-hover);
+      --color-danger-strong-hover: var(--fhi-color-danger-text-inverted);
+      --color-danger-strong-background-active: var(
+        --fhi-color-danger-base-active
+      );
+      --color-danger-strong-border-active: var(--fhi-color-danger-base-hover);
+      --color-danger-strong-active: var(--fhi-color-danger-text-inverted);
+      --color-danger-strong-background-disabled: var(--fhi-color-danger-base);
+      --color-danger-strong-border-disabled: var(--fhi-color-danger-base);
+      --color-danger-strong-disabled: var(--fhi-color-danger-text-inverted);
+
+      --color-danger-subtle-background: var(--fhi-color-danger-surface);
+      --color-danger-subtle-border: var(--fhi-color-danger-surface);
+      --color-danger-subtle: var(--fhi-color-danger-text-subtle);
+      --color-danger-subtle-background-hover: var(
+        --fhi-color-danger-surface-hover
+      );
+      --color-danger-subtle-border-hover: var(--fhi-color-danger-surface-hover);
+      --color-danger-subtle-hover: var(--fhi-color-danger-text);
+      --color-danger-subtle-background-active: var(
+        --fhi-color-danger-surface-active
+      );
+      --color-danger-subtle-border-active: var(
+        --fhi-color-danger-surface-active
+      );
+      --color-danger-subtle-active: var(--fhi-color-danger-text);
+      --color-danger-subtle-background-disabled: var(
+        --fhi-color-danger-surface
+      );
+      --color-danger-subtle-border-disabled: var(--fhi-color-danger-surface);
+      --color-danger-subtle-disabled: var(--fhi-color-danger-text-subtle);
+
+      --color-danger-outlined-background-color: transparent;
+      --color-danger-outlined-border: var(--fhi-color-danger-border);
+      --color-danger-outlined: var(--fhi-color-danger-text-subtle);
+      --color-danger-outlined-background-hover: var(--fhi-color-danger-surface);
+      --color-danger-outlined-border-hover: var(--fhi-color-danger-surface);
+      --color-danger-outlined-hover: var(--fhi-color-danger-text);
+      --color-danger-outlined-background-active: var(
+        --fhi-color-danger-surface-hover
+      );
+      --color-danger-outlined-border-active: var(
+        --fhi-color-danger-surface-hover
+      );
+      --color-danger-outlined-active: var(--fhi-color-danger-text);
+      --color-danger-outlined-background-disabled: transparent;
+      --color-danger-outlined-border-disabled: var(--fhi-color-danger-border);
+      --color-danger-outlined-disabled: var(--fhi-color-danger-text-subtle);
+
+      --color-danger-text-background: transparent;
+      --color-danger-text-border: transparent;
+      --color-danger-text: var(--fhi-color-danger-text-subtle);
+      --color-danger-text-background-hover: var(--fhi-color-danger-surface);
+      --color-danger-text-border-hover: var(--fhi-color-danger-surface);
+      --color-danger-text-hover: var(--fhi-color-danger-text);
+      --color-danger-text-background-active: var(
+        --fhi-color-danger-surface-hover
+      );
+      --color-danger-text-border-active: var(--fhi-color-danger-surface-hover);
+      --color-danger-text-active: var(--fhi-color-danger-text);
+      --color-danger-text-background-disabled: transparent;
+      --color-danger-text-border-disabled: transparent;
+      --color-danger-text-disabled: var(--fhi-color-danger-text-subtle);
+
+      button {
+        border-radius: var(--border-radius);
+        border: solid var(--fhi-border-width);
+        font-family: var(--typography-font-family);
+
+        display: inline-flex;
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: dafn
body: Do you need the `inline-flex`, `justify-content` and `align-items`?
When I remove them nothing seems to change
created_at: 2025-03-12T14:42:24Z
author_association: COLLABORATOR
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: dafn
body: I think the small button is a bit to small. It should be 32px tall, but its only 27px

<img width="1160" alt="Skjermbilde 2025-03-12 kl  15 40 54" src="https://github.com/user-attachments/assets/0bc84e2e-5fe5-470d-a6d6-402b22043409" />

created_at: 2025-03-12T14:45:10Z
author_association: COLLABORATOR
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: dafn
body: Take an extra look at the css and make sure to remove unused tokens and styling
created_at: 2025-03-12T14:47:59Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,659 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+import { ifDefined } from 'lit/directives/if-defined.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  @property({ type: String, reflect: true }) color:
+    | 'accent'
+    | 'neutral'
+    | 'danger' = 'accent';
+
+  @property({ type: String, reflect: true }) variant:
+    | 'strong'
+    | 'subtle'
+    | 'outlined'
+    | 'text' = 'strong';
+
+  @property({ type: String, reflect: true }) size?:
+    | 'large'
+    | 'medium'
+    | 'small' = 'medium';
+
+  @property({ type: Boolean, reflect: true }) disabled = false;
+
+  @property({ type: String }) type?: 'button' | 'submit' | 'reset';
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: dafn
body: The button should have `submit` as default type
created_at: 2025-03-12T14:51:08Z
author_association: COLLABORATOR
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: dafn
body: I have done some testing and it seems like the enter and space functionality is properly implemeneted. We can wait with the automatic test for now. Writing the automatic test is moved to its own issue
created_at: 2025-03-12T15:01:27Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,659 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+import { ifDefined } from 'lit/directives/if-defined.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  @property({ type: String, reflect: true }) color:
+    | 'accent'
+    | 'neutral'
+    | 'danger' = 'accent';
+
+  @property({ type: String, reflect: true }) variant:
+    | 'strong'
+    | 'subtle'
+    | 'outlined'
+    | 'text' = 'strong';
+
+  @property({ type: String, reflect: true }) size?:
+    | 'large'
+    | 'medium'
+    | 'small' = 'medium';
+
+  @property({ type: Boolean, reflect: true }) disabled = false;
+
+  @property({ type: String }) type?: 'button' | 'submit' | 'reset';
+
+  private _formButton!: HTMLButtonElement;
+  private _form!: HTMLFormElement | null;
+
+  constructor() {
+    super();
+    this._stopClickLeak = this._stopClickLeak.bind(this);
+  }
+
+  override connectedCallback(): void {
+    if (!!super.connectedCallback) {
+      super.connectedCallback();
+    }
+
+    this._form = this.closest('form');
+  }
+
+  protected override firstUpdated(): void {
+    this._formButton = document.createElement('button');
+    this._formButton.addEventListener('click', this._stopClickLeak);
+    this.addEventListener('click', this._handleClick);
+  }
+
+  private _handleClick(event: MouseEvent): void {
+    if (
+      (this.type === 'submit' || this.type === 'reset') &&
+      this._form &&
+      !event.defaultPrevented
+    ) {
+      this._formButton.type = this.type;
+      this._form?.appendChild(this._formButton);
+      this._formButton.click();
+      this._form?.removeChild(this._formButton);
+    }
+  }
+
+  private _stopClickLeak(event: MouseEvent): void {
+    if (event.target === this._formButton) {
+      event.stopImmediatePropagation();
+    }
+  }
+
+  render() {
+    return html`<button ?disabled=${this.disabled} type=${ifDefined(this.type)}>
+      <slot></slot>
+    </button>`;
+  }
+
+  static styles = css`
+    :host {
+      --border-radius: var(--fhi-border-radius-full);
+      --typography-font-family: var(--fhi-font-family-roboto-flex);
+      --transition: var(--fhi-duration-quick)
+        cubic-bezier(var(--fhi-ease-default));
+
+      --opacity-disabled: var(--fhi-opacity-disabled);
+
+      --typography-label-font-size-large: var(
+        --fhi-typography-label-large-font-size
+      );
+      --typography-label-font-size-medium: var(
+        --fhi-typography-label-medium-font-size
+      );
+      --typography-label-font-size-small: var(
+        --fhi-typography-label-small-font-size
+      );
+      --typography-label-font-weight-large: var(
+        --fhi-typography-label-font-weight-large
+      );
+      --typography-label-font-weight-medium: var(
+        --fhi-typography-label-medium-font-weight
+      );
+      --typography-label-font-weight-small: var(
+        --fhi-typography-label-small-font-weight
+      );
+      --typography-label-line-height-large: var();
+
+      --typography-label-letter-spacing-large: var(
+        --fhi-typography-label-large-letter-spacing
+      );
+      --typography-label-letter-spacing-medium: var(
+        --fhi-typography-label-medium-letter-spacing
+      );
+      --typography-label-letter-spacing-small: var(
+        --fhi-typography-label-small-letter-spacing
+      );
+      --typography-label-line-height-large: var(
+        --fhi-typography-label-large-line-height
+      );
+      --typography-label-line-height-medium: var(
+        --fhi-typography-label-medium-line-height
+      );
+      --typography-label-line-height-small: var(
+        --fhi-typography-label-medium-line-height
+      );
+
+      --dimension-gap-large: var(--fhi-spacing-100);
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: trybern
body: Gaps are not needed until icons are introduced. They are in Figma since we designed buttons with icons before landing the icon strategy, and scoped the button to not include icons in its first iteration.
created_at: 2025-03-12T15:27:11Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,659 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+import { ifDefined } from 'lit/directives/if-defined.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  @property({ type: String, reflect: true }) color:
+    | 'accent'
+    | 'neutral'
+    | 'danger' = 'accent';
+
+  @property({ type: String, reflect: true }) variant:
+    | 'strong'
+    | 'subtle'
+    | 'outlined'
+    | 'text' = 'strong';
+
+  @property({ type: String, reflect: true }) size?:
+    | 'large'
+    | 'medium'
+    | 'small' = 'medium';
+
+  @property({ type: Boolean, reflect: true }) disabled = false;
+
+  @property({ type: String }) type?: 'button' | 'submit' | 'reset';
+
+  private _formButton!: HTMLButtonElement;
+  private _form!: HTMLFormElement | null;
+
+  constructor() {
+    super();
+    this._stopClickLeak = this._stopClickLeak.bind(this);
+  }
+
+  override connectedCallback(): void {
+    if (!!super.connectedCallback) {
+      super.connectedCallback();
+    }
+
+    this._form = this.closest('form');
+  }
+
+  protected override firstUpdated(): void {
+    this._formButton = document.createElement('button');
+    this._formButton.addEventListener('click', this._stopClickLeak);
+    this.addEventListener('click', this._handleClick);
+  }
+
+  private _handleClick(event: MouseEvent): void {
+    if (
+      (this.type === 'submit' || this.type === 'reset') &&
+      this._form &&
+      !event.defaultPrevented
+    ) {
+      this._formButton.type = this.type;
+      this._form?.appendChild(this._formButton);
+      this._formButton.click();
+      this._form?.removeChild(this._formButton);
+    }
+  }
+
+  private _stopClickLeak(event: MouseEvent): void {
+    if (event.target === this._formButton) {
+      event.stopImmediatePropagation();
+    }
+  }
+
+  render() {
+    return html`<button ?disabled=${this.disabled} type=${ifDefined(this.type)}>
+      <slot></slot>
+    </button>`;
+  }
+
+  static styles = css`
+    :host {
+      --border-radius: var(--fhi-border-radius-full);
+      --typography-font-family: var(--fhi-font-family-roboto-flex);
+      --transition: var(--fhi-duration-quick)
+        cubic-bezier(var(--fhi-ease-default));
+
+      --opacity-disabled: var(--fhi-opacity-disabled);
+
+      --typography-label-font-size-large: var(
+        --fhi-typography-label-large-font-size
+      );
+      --typography-label-font-size-medium: var(
+        --fhi-typography-label-medium-font-size
+      );
+      --typography-label-font-size-small: var(
+        --fhi-typography-label-small-font-size
+      );
+      --typography-label-font-weight-large: var(
+        --fhi-typography-label-font-weight-large
+      );
+      --typography-label-font-weight-medium: var(
+        --fhi-typography-label-medium-font-weight
+      );
+      --typography-label-font-weight-small: var(
+        --fhi-typography-label-small-font-weight
+      );
+      --typography-label-line-height-large: var();
+
+      --typography-label-letter-spacing-large: var(
+        --fhi-typography-label-large-letter-spacing
+      );
+      --typography-label-letter-spacing-medium: var(
+        --fhi-typography-label-medium-letter-spacing
+      );
+      --typography-label-letter-spacing-small: var(
+        --fhi-typography-label-small-letter-spacing
+      );
+      --typography-label-line-height-large: var(
+        --fhi-typography-label-large-line-height
+      );
+      --typography-label-line-height-medium: var(
+        --fhi-typography-label-medium-line-height
+      );
+      --typography-label-line-height-small: var(
+        --fhi-typography-label-medium-line-height
+      );
+
+      --dimension-gap-large: var(--fhi-spacing-100);
+      --dimension-gap-medium: var(--fhi-spacing-050);
+      --dimension-gap-small: var(--fhi-spacing-0);
+
+      --border-width: var(--fhi-border-width);
+
+      --dimension-padding-small: calc(
+          var(--fhi-spacing-050) - var(--fhi-border-width)
+        )
+        var(--fhi-spacing-150);
+      --dimension-padding-medium: calc(
+          var(--fhi-spacing-100) - var(--fhi-border-width)
+        )
+        var(--fhi-spacing-200);
+      --dimension-padding-large: calc(
+          var(--fhi-spacing-200) - var(--fhi-border-width)
+        )
+        var(--fhi-spacing-300);
+      --color-accent-strong-background: var(--fhi-color-accent-base);
+      --color-accent-strong-border: var(--fhi-color-accent-base);
+      --color-accent-strong: var(--fhi-color-accent-text-inverted);
+      --color-accent-strong-background-hover: var(
+        --fhi-color-accent-base-hover
+      );
+      --color-accent-strong-border-hover: var(--fhi-color-accent-base-hover);
+      --color-accent-strong-hover: var(--fhi-color-accent-text-inverted);
+      --color-accent-strong-background-active: var(
+        --fhi-color-accent-base-active
+      );
+      --color-accent-strong-border-active: var(--fhi-color-accent-base-hover);
+      --color-accent-strong-active: var(--fhi-color-accent-text-inverted);
+      --color-accent-strong-background-disabled: var(--fhi-color-accent-base);
+      --color-accent-strong-border-disabled: var(--fhi-color-accent-base);
+      --color-accent-strong-disabled: var(--fhi-color-accent-text-inverted);
+
+      --color-accent-subtle-background: var(--fhi-color-accent-surface);
+      --color-accent-subtle-border: var(--fhi-color-accent-surface);
+      --color-accent-subtle: var(--fhi-color-accent-text-subtle);
+      --color-accent-subtle-background-hover: var(
+        --fhi-color-accent-surface-hover
+      );
+      --color-accent-subtle-border-hover: var(--fhi-color-accent-surface-hover);
+      --color-accent-subtle-hover: var(--fhi-color-accent-text);
+      --color-accent-subtle-background-active: var(
+        --fhi-color-accent-surface-active
+      );
+      --color-accent-subtle-border-active: var(
+        --fhi-color-accent-surface-active
+      );
+      --color-accent-subtle-active: var(--fhi-color-accent-text);
+      --color-accent-subtle-background-disabled: var(
+        --fhi-color-accent-surface
+      );
+      --color-accent-subtle-border-disabled: var(--fhi-color-accent-surface);
+      --color-accent-subtle-disabled: var(--fhi-color-accent-text-subtle);
+
+      --color-accent-outlined-background: transparent;
+      --color-accent-outlined-border: var(--fhi-color-accent-border);
+      --color-accent-outlined: var(--fhi-color-accent-text-subtle);
+      --color-accent-outlined-background-hover: var(--fhi-color-accent-surface);
+      --color-accent-outlined-border-hover: var(--fhi-color-accent-surface);
+      --color-accent-outlined-hover: var(--fhi-color-accent-text);
+      --color-accent-outlined-background-active: var(
+        --fhi-color-accent-surface-hover
+      );
+      --color-accent-outlined-border-active: var(
+        --fhi-color-accent-surface-hover
+      );
+      --color-accent-outlined-active: var(--fhi-color-accent-text);
+      --color-accent-outlined-background-disabled: transparent;
+      --color-accent-outlined-border-disabled: var(--fhi-color-surface-base);
+      --color-accent-outlined-disabled: var(--fhi-color-accent-text-subtle);
+
+      --color-accent-text-background: transparent;
+      --color-accent-text-border: transparent;
+      --color-accent-text: var(--fhi-color-accent-text-subtle);
+      --color-accent-text-background-hover: var(--fhi-color-accent-surface);
+      --color-accent-text-border-hover: var(--fhi-color-accent-surface);
+      --color-accent-text-hover: var(--fhi-color-accent-text);
+      --color-accent-text-background-active: var(
+        --fhi-color-accent-surface-hover
+      );
+      --color-accent-text-border-active: var(--fhi-color-accent-surface-hover);
+      --color-accent-text-active: var(--fhi-color-accent-text);
+      --color-accent-text-background-disabled: transparent;
+      --color-accent-text-border-disabled: transparent;
+      --color-accent-text-disabled: var(--fhi-color-accent-text);
+
+      --color-neutral-strong-background: var(--fhi-color-neutral-base);
+      --color-neutral-strong-border: var(--fhi-color-neutral-base);
+      --color-neutral-strong: var(--fhi-color-neutral-text-inverted);
+      --color-neutral-strong-background-hover: var(
+        --fhi-color-neutral-base-hover
+      );
+      --color-neutral-strong-border-hover: var(--fhi-color-neutral-base-hover);
+      --color-neutral-strong-hover: var(--fhi-color-neutral-text-inverted);
+      --color-neutral-strong-background-active: var(
+        --fhi-color-neutral-base-active
+      );
+      --color-neutral-strong-border-active: var(--fhi-color-neutral-base-hover);
+      --color-neutral-strong-active: var(--fhi-color-neutral-text-inverted);
+      --color-neutral-strong-background-disabled: var(--fhi-color-neutral-base);
+      --color-neutral-strong-border-disabled: var(--fhi-color-neutral-base);
+      --color-neutral-strong-disabled: var(--fhi-color-neutral-text-inverted);
+
+      --color-neutral-subtle-background: var(--fhi-color-neutral-surface);
+      --color-neutral-subtle-border: var(--fhi-color-neutral-surface);
+      --color-neutral-subtle: var(--fhi-color-neutral-text-subtle);
+      --color-neutral-subtle-background-hover: var(
+        --fhi-color-neutral-surface-hover
+      );
+      --color-neutral-subtle-border-hover: var(
+        --fhi-color-neutral-surface-hover
+      );
+      --color-neutral-subtle-hover: var(--fhi-color-neutral-text);
+      --color-neutral-subtle-background-active: var(
+        --fhi-color-neutral-surface-active
+      );
+      --color-neutral-subtle-border-active: var(
+        --fhi-color-neutral-surface-active
+      );
+      --color-neutral-subtle-active: var(--fhi-color-neutral-text);
+      --color-neutral-subtle-background-disabled: var(
+        --fhi-color-neutral-surface
+      );
+      --color-neutral-subtle-border-disabled: var(--fhi-color-neutral-surface);
+      --color-neutral-subtle-disabled: var(--fhi-color-neutral-text);
+
+      --color-neutral-outlined-background: transparent;
+      --color-neutral-outlined-border: var(--fhi-color-neutral-border);
+      --color-neutral-outlined: var(--fhi-color-neutral-text-subtle);
+      --color-neutral-outlined-background-hover: var(
+        --fhi-color-neutral-surface
+      );
+      --color-neutral-outlined-border-hover: var(--fhi-color-neutral-surface);
+      --color-neutral-outlined-hover: var(--fhi-color-neutral-text);
+      --color-neutral-outlined-background-active: var(
+        --fhi-color-neutral-surface-hover
+      );
+      --color-neutral-outlined-border-active: var(
+        --fhi-color-neutral-surface-hover
+      );
+      --color-neutral-outlined-active: var(--fhi-color-neutral-text);
+      --color-neutral-outlined-background-disabled: transparent;
+      --color-neutral-outlined-border-disabled: var(--fhi-color-surface-base);
+      --color-neutral-outlined-disabled: var(--fhi-color-neutral-text-subtle);
+
+      --color-neutral-text-background: transparent;
+      --color-neutral-text-border: transparent;
+      --color-neutral-text: var(--fhi-color-neutral-text-subtle);
+      --color-neutral-text-background-hover: var(--fhi-color-neutral-surface);
+      --color-neutral-text-border-hover: var(--fhi-color-neutral-surface);
+      --color-neutral-text-hover: var(--fhi-color-neutral-text);
+      --color-neutral-text-background-active: var(
+        --fhi-color-neutral-surface-hover
+      );
+      --color-neutral-text-border-active: var(
+        --fhi-color-neutral-surface-hover
+      );
+      --color-neutral-text-active: var(--fhi-color-neutral-text);
+      --color-neutral-text-background-disabled: transparent;
+      --color-neutral-text-border-disabled: transparent;
+      --color-neutral-text-disaabled: var(--fhi-color-neutral-text-subtle);
+
+      --color-danger-strong-background: var(--fhi-color-danger-base);
+      --color-danger-strong-border: var(--fhi-color-danger-base);
+      --color-danger-strong: var(--fhi-color-danger-text-inverted);
+      --color-danger-strong-background-hover: var(
+        --fhi-color-danger-base-hover
+      );
+      --color-danger-strong-border-hover: var(--fhi-color-danger-base-hover);
+      --color-danger-strong-hover: var(--fhi-color-danger-text-inverted);
+      --color-danger-strong-background-active: var(
+        --fhi-color-danger-base-active
+      );
+      --color-danger-strong-border-active: var(--fhi-color-danger-base-hover);
+      --color-danger-strong-active: var(--fhi-color-danger-text-inverted);
+      --color-danger-strong-background-disabled: var(--fhi-color-danger-base);
+      --color-danger-strong-border-disabled: var(--fhi-color-danger-base);
+      --color-danger-strong-disabled: var(--fhi-color-danger-text-inverted);
+
+      --color-danger-subtle-background: var(--fhi-color-danger-surface);
+      --color-danger-subtle-border: var(--fhi-color-danger-surface);
+      --color-danger-subtle: var(--fhi-color-danger-text-subtle);
+      --color-danger-subtle-background-hover: var(
+        --fhi-color-danger-surface-hover
+      );
+      --color-danger-subtle-border-hover: var(--fhi-color-danger-surface-hover);
+      --color-danger-subtle-hover: var(--fhi-color-danger-text);
+      --color-danger-subtle-background-active: var(
+        --fhi-color-danger-surface-active
+      );
+      --color-danger-subtle-border-active: var(
+        --fhi-color-danger-surface-active
+      );
+      --color-danger-subtle-active: var(--fhi-color-danger-text);
+      --color-danger-subtle-background-disabled: var(
+        --fhi-color-danger-surface
+      );
+      --color-danger-subtle-border-disabled: var(--fhi-color-danger-surface);
+      --color-danger-subtle-disabled: var(--fhi-color-danger-text-subtle);
+
+      --color-danger-outlined-background-color: transparent;
+      --color-danger-outlined-border: var(--fhi-color-danger-border);
+      --color-danger-outlined: var(--fhi-color-danger-text-subtle);
+      --color-danger-outlined-background-hover: var(--fhi-color-danger-surface);
+      --color-danger-outlined-border-hover: var(--fhi-color-danger-surface);
+      --color-danger-outlined-hover: var(--fhi-color-danger-text);
+      --color-danger-outlined-background-active: var(
+        --fhi-color-danger-surface-hover
+      );
+      --color-danger-outlined-border-active: var(
+        --fhi-color-danger-surface-hover
+      );
+      --color-danger-outlined-active: var(--fhi-color-danger-text);
+      --color-danger-outlined-background-disabled: transparent;
+      --color-danger-outlined-border-disabled: var(--fhi-color-danger-border);
+      --color-danger-outlined-disabled: var(--fhi-color-danger-text-subtle);
+
+      --color-danger-text-background: transparent;
+      --color-danger-text-border: transparent;
+      --color-danger-text: var(--fhi-color-danger-text-subtle);
+      --color-danger-text-background-hover: var(--fhi-color-danger-surface);
+      --color-danger-text-border-hover: var(--fhi-color-danger-surface);
+      --color-danger-text-hover: var(--fhi-color-danger-text);
+      --color-danger-text-background-active: var(
+        --fhi-color-danger-surface-hover
+      );
+      --color-danger-text-border-active: var(--fhi-color-danger-surface-hover);
+      --color-danger-text-active: var(--fhi-color-danger-text);
+      --color-danger-text-background-disabled: transparent;
+      --color-danger-text-border-disabled: transparent;
+      --color-danger-text-disabled: var(--fhi-color-danger-text-subtle);
+
+      button {
+        border-radius: var(--border-radius);
+        border: solid var(--fhi-border-width);
+        font-family: var(--typography-font-family);
+
+        display: inline-flex;
+        justify-content: center;
+        align-items: center;
+
+        transition: var(--transition);
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: trybern
body: `var(--transition)` contains a redundant cubic-bezier. 

Change it from
> `var(--fhi-duration-quick) cubic-bezier(var(--fhi-ease-default))`

to

> `var(--fhi-duration-quick) var(--fhi-ease-default)`

and the transition works as expected. 

created_at: 2025-03-12T15:33:00Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,659 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+import { ifDefined } from 'lit/directives/if-defined.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  @property({ type: String, reflect: true }) color:
+    | 'accent'
+    | 'neutral'
+    | 'danger' = 'accent';
+
+  @property({ type: String, reflect: true }) variant:
+    | 'strong'
+    | 'subtle'
+    | 'outlined'
+    | 'text' = 'strong';
+
+  @property({ type: String, reflect: true }) size?:
+    | 'large'
+    | 'medium'
+    | 'small' = 'medium';
+
+  @property({ type: Boolean, reflect: true }) disabled = false;
+
+  @property({ type: String }) type?: 'button' | 'submit' | 'reset';
+
+  private _formButton!: HTMLButtonElement;
+  private _form!: HTMLFormElement | null;
+
+  constructor() {
+    super();
+    this._stopClickLeak = this._stopClickLeak.bind(this);
+  }
+
+  override connectedCallback(): void {
+    if (!!super.connectedCallback) {
+      super.connectedCallback();
+    }
+
+    this._form = this.closest('form');
+  }
+
+  protected override firstUpdated(): void {
+    this._formButton = document.createElement('button');
+    this._formButton.addEventListener('click', this._stopClickLeak);
+    this.addEventListener('click', this._handleClick);
+  }
+
+  private _handleClick(event: MouseEvent): void {
+    if (
+      (this.type === 'submit' || this.type === 'reset') &&
+      this._form &&
+      !event.defaultPrevented
+    ) {
+      this._formButton.type = this.type;
+      this._form?.appendChild(this._formButton);
+      this._formButton.click();
+      this._form?.removeChild(this._formButton);
+    }
+  }
+
+  private _stopClickLeak(event: MouseEvent): void {
+    if (event.target === this._formButton) {
+      event.stopImmediatePropagation();
+    }
+  }
+
+  render() {
+    return html`<button ?disabled=${this.disabled} type=${ifDefined(this.type)}>
+      <slot></slot>
+    </button>`;
+  }
+
+  static styles = css`
+    :host {
+      --border-radius: var(--fhi-border-radius-full);
+      --typography-font-family: var(--fhi-font-family-roboto-flex);
+      --transition: var(--fhi-duration-quick)
+        cubic-bezier(var(--fhi-ease-default));
+
+      --opacity-disabled: var(--fhi-opacity-disabled);
+
+      --typography-label-font-size-large: var(
+        --fhi-typography-label-large-font-size
+      );
+      --typography-label-font-size-medium: var(
+        --fhi-typography-label-medium-font-size
+      );
+      --typography-label-font-size-small: var(
+        --fhi-typography-label-small-font-size
+      );
+      --typography-label-font-weight-large: var(
+        --fhi-typography-label-font-weight-large
+      );
+      --typography-label-font-weight-medium: var(
+        --fhi-typography-label-medium-font-weight
+      );
+      --typography-label-font-weight-small: var(
+        --fhi-typography-label-small-font-weight
+      );
+      --typography-label-line-height-large: var();
+
+      --typography-label-letter-spacing-large: var(
+        --fhi-typography-label-large-letter-spacing
+      );
+      --typography-label-letter-spacing-medium: var(
+        --fhi-typography-label-medium-letter-spacing
+      );
+      --typography-label-letter-spacing-small: var(
+        --fhi-typography-label-small-letter-spacing
+      );
+      --typography-label-line-height-large: var(
+        --fhi-typography-label-large-line-height
+      );
+      --typography-label-line-height-medium: var(
+        --fhi-typography-label-medium-line-height
+      );
+      --typography-label-line-height-small: var(
+        --fhi-typography-label-medium-line-height
+      );
+
+      --dimension-gap-large: var(--fhi-spacing-100);
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: dafn
body: I see, then we do not need the gap here as the Icon implementation is not a part of this PR. It should be removed for now as it is dead code.
created_at: 2025-03-13T09:02:46Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1,63 @@
+import { FhiButton } from './fhi-button.ts';
+import * as FhiButtonStories from './fhi-button.stories.ts';
+import {
+  Meta,
+  Title,
+  Primary,
+  Canvas,
+  Story,
+  Controls,
+} from '@storybook/blocks';
+
+<Meta of={FhiButtonStories} />
+
+# Button
+
+Knapper lar brukere sette i gang handlinger, som å lagre, sende inn skjemaer,
+navigere seg videre og andre spesifikke oppgaver.
+
+## Passer til
+
+- Å utføre spesifikke handlinger, slik som å sende inn et skjemasvar eller åpne en meny.
+
+- Å starte, navigere seg gjennom og avslutte en flyt eller prosess, for eksempel med «Neste» eller «Gå videre».
+
+<Canvas of={FhiButtonStories.Preview} />
+
+<Controls />
+
+## Valg
+
+Ulike varianter og størrelser kan gi knappen ulike vekter av fremheving, for å skape hierarki og veilede oppmerksomheten til brukeren.
+
+### Color (Farge)
+
+- `accent` Default. Knapper som skal ta oppmerksomhet og stå ut. Brukes gjerne for å gå videre eller avslutte en flyt.
+
+- `neutral` Brukes på handlinger som ikke trenger mye oppmerksomhet. Mye bruk av `neutral` forsterker bruk av `accent`, når du trenger det.
+
+- `danger` Signaliserer destruktive handlinger, for eksempel der data slettes eller handlinger ikke kan reverseres.
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.docs.mdx
user: login: trybern
body: ```suggestion
- `danger` Signaliserer destruktive handlinger, for eksempel der data slettes eller handlinger som ikke kan angres.
```
created_at: 2025-03-17T10:04:05Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,649 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  @property({ type: String, reflect: true }) color:
+    | 'accent'
+    | 'neutral'
+    | 'danger' = 'accent';
+
+  @property({ type: String, reflect: true }) variant:
+    | 'strong'
+    | 'subtle'
+    | 'outlined'
+    | 'text' = 'strong';
+
+  @property({ type: String, reflect: true }) size:
+    | 'large'
+    | 'medium'
+    | 'small' = 'medium';
+
+  @property({ type: Boolean, reflect: true }) disabled = false;
+
+  @property({ type: String }) type: 'button' | 'submit' | 'reset' = 'submit';
+
+  private _formButton!: HTMLButtonElement;
+  private _form!: HTMLFormElement | null;
+
+  constructor() {
+    super();
+    this._stopClickLeak = this._stopClickLeak.bind(this);
+  }
+
+  override connectedCallback(): void {
+    if (!!super.connectedCallback) {
+      super.connectedCallback();
+    }
+
+    this._form = this.closest('form');
+  }
+
+  protected override firstUpdated(): void {
+    this._formButton = document.createElement('button');
+    this._formButton.addEventListener('click', this._stopClickLeak);
+    this.addEventListener('click', this._handleClick);
+  }
+
+  private _handleClick(event: MouseEvent): void {
+    if (
+      (this.type === 'submit' || this.type === 'reset') &&
+      this._form &&
+      !event.defaultPrevented
+    ) {
+      this._formButton.type = this.type;
+      this._form?.appendChild(this._formButton);
+      this._formButton.click();
+      this._form?.removeChild(this._formButton);
+    }
+  }
+
+  private _stopClickLeak(event: MouseEvent): void {
+    if (event.target === this._formButton) {
+      event.stopImmediatePropagation();
+    }
+  }
+
+  render() {
+    return html`<button ?disabled=${this.disabled} type=${this.type}>
+      <slot></slot>
+    </button>`;
+  }
+
+  static styles = css`
+    :host {
+      --dimension-border-radius: var(--fhi-border-radius-full);
+      --dimension-border-width: var(--fhi-dimension-border-width);
+      --typography-font-family: var(--fhi-font-family-roboto-flex);
+      --motion-transition: var(--fhi-motion-duration-quick)
+        var(--fhi-motion-ease-default);
+
+      --opacity-disabled: var(--fhi-opacity-disabled);
+
+      --typography-label-font-size-large: var(
+        --fhi-typography-label-large-font-size
+      );
+      --typography-label-font-size-medium: var(
+        --fhi-typography-label-medium-font-size
+      );
+      --typography-label-font-size-small: var(
+        --fhi-typography-label-small-font-size
+      );
+      --typography-label-font-weight-large: var(
+        --fhi-typography-label-font-weight-large
+      );
+      --typography-label-font-weight-medium: var(
+        --fhi-typography-label-medium-font-weight
+      );
+      --typography-label-font-weight-small: var(
+        --fhi-typography-label-small-font-weight
+      );
+      --typography-label-letter-spacing-large: var(
+        --fhi-typography-label-large-letter-spacing
+      );
+      --typography-label-letter-spacing-medium: var(
+        --fhi-typography-label-medium-letter-spacing
+      );
+      --typography-label-letter-spacing-small: var(
+        --fhi-typography-label-small-letter-spacing
+      );
+      --typography-label-line-height-large: var(
+        --fhi-typography-label-large-line-height
+      );
+      --typography-label-line-height-medium: var(
+        --fhi-typography-label-medium-line-height
+      );
+      --typography-label-line-height-small: var(
+        --fhi-typography-label-medium-line-height
+      );
+
+      --dimension-padding-small: calc(
+          var(--fhi-spacing-050) - var(--fhi-dimension-border-width)
+        )
+        calc(
+          var(--fhi-spacing-150) +
+            var(--fhi-spacing-050) - var(--fhi-dimension-border-width)
+        );
+      --dimension-padding-medium: calc(
+          var(--fhi-spacing-100) - var(--fhi-dimension-border-width)
+        )
+        calc(
+          var(--fhi-spacing-200) +
+            var(--fhi-spacing-050) - var(--fhi-dimension-border-width)
+        );
+      --dimension-padding-large: calc(
+          var(--fhi-spacing-200) - var(--fhi-dimension-border-width)
+        )
+        calc(
+          var(--fhi-spacing-300) +
+            var(--fhi-spacing-050) - var(--fhi-dimension-border-width)
+        );
+      --color-accent-strong-background: var(--fhi-color-accent-base);
+      --color-accent-strong-border: var(--fhi-color-accent-base);
+      --color-accent-strong: var(--fhi-color-accent-text-inverted);
+      --color-accent-strong-background-hover: var(
+        --fhi-color-accent-base-hover
+      );
+      --color-accent-strong-border-hover: var(--fhi-color-accent-base-hover);
+      --color-accent-strong-hover: var(--fhi-color-accent-text-inverted);
+      --color-accent-strong-background-active: var(
+        --fhi-color-accent-base-active
+      );
+      --color-accent-strong-border-active: var(--fhi-color-accent-base-hover);
+      --color-accent-strong-active: var(--fhi-color-accent-text-inverted);
+      --color-accent-strong-background-disabled: var(--fhi-color-accent-base);
+      --color-accent-strong-border-disabled: var(--fhi-color-accent-base);
+      --color-accent-strong-disabled: var(--fhi-color-accent-text-inverted);
+
+      --color-accent-subtle-background: var(--fhi-color-accent-surface);
+      --color-accent-subtle-border: var(--fhi-color-accent-surface);
+      --color-accent-subtle: var(--fhi-color-accent-text-subtle);
+      --color-accent-subtle-background-hover: var(
+        --fhi-color-accent-surface-hover
+      );
+      --color-accent-subtle-border-hover: var(--fhi-color-accent-surface-hover);
+      --color-accent-subtle-hover: var(--fhi-color-accent-text);
+      --color-accent-subtle-background-active: var(
+        --fhi-color-accent-surface-active
+      );
+      --color-accent-subtle-border-active: var(
+        --fhi-color-accent-surface-active
+      );
+      --color-accent-subtle-active: var(--fhi-color-accent-text);
+      --color-accent-subtle-background-disabled: var(
+        --fhi-color-accent-surface
+      );
+      --color-accent-subtle-border-disabled: var(--fhi-color-accent-surface);
+      --color-accent-subtle-disabled: var(--fhi-color-accent-text-subtle);
+
+      --color-accent-outlined-background: transparent;
+      --color-accent-outlined-border: var(--fhi-color-accent-border);
+      --color-accent-outlined: var(--fhi-color-accent-text-subtle);
+      --color-accent-outlined-background-hover: var(--fhi-color-accent-surface);
+      --color-accent-outlined-border-hover: var(--fhi-color-accent-surface);
+      --color-accent-outlined-hover: var(--fhi-color-accent-text);
+      --color-accent-outlined-background-active: var(
+        --fhi-color-accent-surface-hover
+      );
+      --color-accent-outlined-border-active: var(
+        --fhi-color-accent-surface-hover
+      );
+      --color-accent-outlined-active: var(--fhi-color-accent-text);
+      --color-accent-outlined-background-disabled: transparent;
+      --color-accent-outlined-border-disabled: var(--fhi-color-surface-base);
+      --color-accent-outlined-disabled: var(--fhi-color-accent-text-subtle);
+
+      --color-accent-text-background: transparent;
+      --color-accent-text-border: transparent;
+      --color-accent-text: var(--fhi-color-accent-text-subtle);
+      --color-accent-text-background-hover: var(--fhi-color-accent-surface);
+      --color-accent-text-border-hover: var(--fhi-color-accent-surface);
+      --color-accent-text-hover: var(--fhi-color-accent-text);
+      --color-accent-text-background-active: var(
+        --fhi-color-accent-surface-hover
+      );
+      --color-accent-text-border-active: var(--fhi-color-accent-surface-hover);
+      --color-accent-text-active: var(--fhi-color-accent-text);
+      --color-accent-text-background-disabled: transparent;
+      --color-accent-text-border-disabled: transparent;
+      --color-accent-text-disabled: var(--fhi-color-accent-text);
+
+      --color-neutral-strong-background: var(--fhi-color-neutral-base);
+      --color-neutral-strong-border: var(--fhi-color-neutral-base);
+      --color-neutral-strong: var(--fhi-color-neutral-text-inverted);
+      --color-neutral-strong-background-hover: var(
+        --fhi-color-neutral-base-hover
+      );
+      --color-neutral-strong-border-hover: var(--fhi-color-neutral-base-hover);
+      --color-neutral-strong-hover: var(--fhi-color-neutral-text-inverted);
+      --color-neutral-strong-background-active: var(
+        --fhi-color-neutral-base-active
+      );
+      --color-neutral-strong-border-active: var(--fhi-color-neutral-base-hover);
+      --color-neutral-strong-active: var(--fhi-color-neutral-text-inverted);
+      --color-neutral-strong-background-disabled: var(--fhi-color-neutral-base);
+      --color-neutral-strong-border-disabled: var(--fhi-color-neutral-base);
+      --color-neutral-strong-disabled: var(--fhi-color-neutral-text-inverted);
+
+      --color-neutral-subtle-background: var(--fhi-color-neutral-surface);
+      --color-neutral-subtle-border: var(--fhi-color-neutral-surface);
+      --color-neutral-subtle: var(--fhi-color-neutral-text-subtle);
+      --color-neutral-subtle-background-hover: var(
+        --fhi-color-neutral-surface-hover
+      );
+      --color-neutral-subtle-border-hover: var(
+        --fhi-color-neutral-surface-hover
+      );
+      --color-neutral-subtle-hover: var(--fhi-color-neutral-text);
+      --color-neutral-subtle-background-active: var(
+        --fhi-color-neutral-surface-active
+      );
+      --color-neutral-subtle-border-active: var(
+        --fhi-color-neutral-surface-active
+      );
+      --color-neutral-subtle-active: var(--fhi-color-neutral-text);
+      --color-neutral-subtle-background-disabled: var(
+        --fhi-color-neutral-surface
+      );
+      --color-neutral-subtle-border-disabled: var(--fhi-color-neutral-surface);
+      --color-neutral-subtle-disabled: var(--fhi-color-neutral-text);
+
+      --color-neutral-outlined-background: transparent;
+      --color-neutral-outlined-border: var(--fhi-color-neutral-border);
+      --color-neutral-outlined: var(--fhi-color-neutral-text-subtle);
+      --color-neutral-outlined-background-hover: var(
+        --fhi-color-neutral-surface
+      );
+      --color-neutral-outlined-border-hover: var(--fhi-color-neutral-surface);
+      --color-neutral-outlined-hover: var(--fhi-color-neutral-text);
+      --color-neutral-outlined-background-active: var(
+        --fhi-color-neutral-surface-hover
+      );
+      --color-neutral-outlined-border-active: var(
+        --fhi-color-neutral-surface-hover
+      );
+      --color-neutral-outlined-active: var(--fhi-color-neutral-text);
+      --color-neutral-outlined-background-disabled: transparent;
+      --color-neutral-outlined-border-disabled: var(--fhi-color-surface-base);
+      --color-neutral-outlined-disabled: var(--fhi-color-neutral-text-subtle);
+
+      --color-neutral-text-background: transparent;
+      --color-neutral-text-border: transparent;
+      --color-neutral-text: var(--fhi-color-neutral-text-subtle);
+      --color-neutral-text-background-hover: var(--fhi-color-neutral-surface);
+      --color-neutral-text-border-hover: var(--fhi-color-neutral-surface);
+      --color-neutral-text-hover: var(--fhi-color-neutral-text);
+      --color-neutral-text-background-active: var(
+        --fhi-color-neutral-surface-hover
+      );
+      --color-neutral-text-border-active: var(
+        --fhi-color-neutral-surface-hover
+      );
+      --color-neutral-text-active: var(--fhi-color-neutral-text);
+      --color-neutral-text-background-disabled: transparent;
+      --color-neutral-text-border-disabled: transparent;
+      --color-neutral-text-disaabled: var(--fhi-color-neutral-text-subtle);
+
+      --color-danger-strong-background: var(--fhi-color-danger-base);
+      --color-danger-strong-border: var(--fhi-color-danger-base);
+      --color-danger-strong: var(--fhi-color-danger-text-inverted);
+      --color-danger-strong-background-hover: var(
+        --fhi-color-danger-base-hover
+      );
+      --color-danger-strong-border-hover: var(--fhi-color-danger-base-hover);
+      --color-danger-strong-hover: var(--fhi-color-danger-text-inverted);
+      --color-danger-strong-background-active: var(
+        --fhi-color-danger-base-active
+      );
+      --color-danger-strong-border-active: var(--fhi-color-danger-base-hover);
+      --color-danger-strong-active: var(--fhi-color-danger-text-inverted);
+      --color-danger-strong-background-disabled: var(--fhi-color-danger-base);
+      --color-danger-strong-border-disabled: var(--fhi-color-danger-base);
+      --color-danger-strong-disabled: var(--fhi-color-danger-text-inverted);
+
+      --color-danger-subtle-background: var(--fhi-color-danger-surface);
+      --color-danger-subtle-border: var(--fhi-color-danger-surface);
+      --color-danger-subtle: var(--fhi-color-danger-text-subtle);
+      --color-danger-subtle-background-hover: var(
+        --fhi-color-danger-surface-hover
+      );
+      --color-danger-subtle-border-hover: var(--fhi-color-danger-surface-hover);
+      --color-danger-subtle-hover: var(--fhi-color-danger-text);
+      --color-danger-subtle-background-active: var(
+        --fhi-color-danger-surface-active
+      );
+      --color-danger-subtle-border-active: var(
+        --fhi-color-danger-surface-active
+      );
+      --color-danger-subtle-active: var(--fhi-color-danger-text);
+      --color-danger-subtle-background-disabled: var(
+        --fhi-color-danger-surface
+      );
+      --color-danger-subtle-border-disabled: var(--fhi-color-danger-surface);
+      --color-danger-subtle-disabled: var(--fhi-color-danger-text-subtle);
+
+      --color-danger-outlined-background-color: transparent;
+      --color-danger-outlined-border: var(--fhi-color-danger-border);
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: trybern
body: ```suggestion
      --color-danger-outlined-border: var(--fhi-color-danger-border-subtle);
```
created_at: 2025-03-26T07:51:30Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,649 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  @property({ type: String, reflect: true }) color:
+    | 'accent'
+    | 'neutral'
+    | 'danger' = 'accent';
+
+  @property({ type: String, reflect: true }) variant:
+    | 'strong'
+    | 'subtle'
+    | 'outlined'
+    | 'text' = 'strong';
+
+  @property({ type: String, reflect: true }) size:
+    | 'large'
+    | 'medium'
+    | 'small' = 'medium';
+
+  @property({ type: Boolean, reflect: true }) disabled = false;
+
+  @property({ type: String }) type: 'button' | 'submit' | 'reset' = 'submit';
+
+  private _formButton!: HTMLButtonElement;
+  private _form!: HTMLFormElement | null;
+
+  constructor() {
+    super();
+    this._stopClickLeak = this._stopClickLeak.bind(this);
+  }
+
+  override connectedCallback(): void {
+    if (!!super.connectedCallback) {
+      super.connectedCallback();
+    }
+
+    this._form = this.closest('form');
+  }
+
+  protected override firstUpdated(): void {
+    this._formButton = document.createElement('button');
+    this._formButton.addEventListener('click', this._stopClickLeak);
+    this.addEventListener('click', this._handleClick);
+  }
+
+  private _handleClick(event: MouseEvent): void {
+    if (
+      (this.type === 'submit' || this.type === 'reset') &&
+      this._form &&
+      !event.defaultPrevented
+    ) {
+      this._formButton.type = this.type;
+      this._form?.appendChild(this._formButton);
+      this._formButton.click();
+      this._form?.removeChild(this._formButton);
+    }
+  }
+
+  private _stopClickLeak(event: MouseEvent): void {
+    if (event.target === this._formButton) {
+      event.stopImmediatePropagation();
+    }
+  }
+
+  render() {
+    return html`<button ?disabled=${this.disabled} type=${this.type}>
+      <slot></slot>
+    </button>`;
+  }
+
+  static styles = css`
+    :host {
+      --dimension-border-radius: var(--fhi-border-radius-full);
+      --dimension-border-width: var(--fhi-dimension-border-width);
+      --typography-font-family: var(--fhi-font-family-roboto-flex);
+      --motion-transition: var(--fhi-motion-duration-quick)
+        var(--fhi-motion-ease-default);
+
+      --opacity-disabled: var(--fhi-opacity-disabled);
+
+      --typography-label-font-size-large: var(
+        --fhi-typography-label-large-font-size
+      );
+      --typography-label-font-size-medium: var(
+        --fhi-typography-label-medium-font-size
+      );
+      --typography-label-font-size-small: var(
+        --fhi-typography-label-small-font-size
+      );
+      --typography-label-font-weight-large: var(
+        --fhi-typography-label-font-weight-large
+      );
+      --typography-label-font-weight-medium: var(
+        --fhi-typography-label-medium-font-weight
+      );
+      --typography-label-font-weight-small: var(
+        --fhi-typography-label-small-font-weight
+      );
+      --typography-label-letter-spacing-large: var(
+        --fhi-typography-label-large-letter-spacing
+      );
+      --typography-label-letter-spacing-medium: var(
+        --fhi-typography-label-medium-letter-spacing
+      );
+      --typography-label-letter-spacing-small: var(
+        --fhi-typography-label-small-letter-spacing
+      );
+      --typography-label-line-height-large: var(
+        --fhi-typography-label-large-line-height
+      );
+      --typography-label-line-height-medium: var(
+        --fhi-typography-label-medium-line-height
+      );
+      --typography-label-line-height-small: var(
+        --fhi-typography-label-medium-line-height
+      );
+
+      --dimension-padding-small: calc(
+          var(--fhi-spacing-050) - var(--fhi-dimension-border-width)
+        )
+        calc(
+          var(--fhi-spacing-150) +
+            var(--fhi-spacing-050) - var(--fhi-dimension-border-width)
+        );
+      --dimension-padding-medium: calc(
+          var(--fhi-spacing-100) - var(--fhi-dimension-border-width)
+        )
+        calc(
+          var(--fhi-spacing-200) +
+            var(--fhi-spacing-050) - var(--fhi-dimension-border-width)
+        );
+      --dimension-padding-large: calc(
+          var(--fhi-spacing-200) - var(--fhi-dimension-border-width)
+        )
+        calc(
+          var(--fhi-spacing-300) +
+            var(--fhi-spacing-050) - var(--fhi-dimension-border-width)
+        );
+      --color-accent-strong-background: var(--fhi-color-accent-base);
+      --color-accent-strong-border: var(--fhi-color-accent-base);
+      --color-accent-strong: var(--fhi-color-accent-text-inverted);
+      --color-accent-strong-background-hover: var(
+        --fhi-color-accent-base-hover
+      );
+      --color-accent-strong-border-hover: var(--fhi-color-accent-base-hover);
+      --color-accent-strong-hover: var(--fhi-color-accent-text-inverted);
+      --color-accent-strong-background-active: var(
+        --fhi-color-accent-base-active
+      );
+      --color-accent-strong-border-active: var(--fhi-color-accent-base-hover);
+      --color-accent-strong-active: var(--fhi-color-accent-text-inverted);
+      --color-accent-strong-background-disabled: var(--fhi-color-accent-base);
+      --color-accent-strong-border-disabled: var(--fhi-color-accent-base);
+      --color-accent-strong-disabled: var(--fhi-color-accent-text-inverted);
+
+      --color-accent-subtle-background: var(--fhi-color-accent-surface);
+      --color-accent-subtle-border: var(--fhi-color-accent-surface);
+      --color-accent-subtle: var(--fhi-color-accent-text-subtle);
+      --color-accent-subtle-background-hover: var(
+        --fhi-color-accent-surface-hover
+      );
+      --color-accent-subtle-border-hover: var(--fhi-color-accent-surface-hover);
+      --color-accent-subtle-hover: var(--fhi-color-accent-text);
+      --color-accent-subtle-background-active: var(
+        --fhi-color-accent-surface-active
+      );
+      --color-accent-subtle-border-active: var(
+        --fhi-color-accent-surface-active
+      );
+      --color-accent-subtle-active: var(--fhi-color-accent-text);
+      --color-accent-subtle-background-disabled: var(
+        --fhi-color-accent-surface
+      );
+      --color-accent-subtle-border-disabled: var(--fhi-color-accent-surface);
+      --color-accent-subtle-disabled: var(--fhi-color-accent-text-subtle);
+
+      --color-accent-outlined-background: transparent;
+      --color-accent-outlined-border: var(--fhi-color-accent-border);
+      --color-accent-outlined: var(--fhi-color-accent-text-subtle);
+      --color-accent-outlined-background-hover: var(--fhi-color-accent-surface);
+      --color-accent-outlined-border-hover: var(--fhi-color-accent-surface);
+      --color-accent-outlined-hover: var(--fhi-color-accent-text);
+      --color-accent-outlined-background-active: var(
+        --fhi-color-accent-surface-hover
+      );
+      --color-accent-outlined-border-active: var(
+        --fhi-color-accent-surface-hover
+      );
+      --color-accent-outlined-active: var(--fhi-color-accent-text);
+      --color-accent-outlined-background-disabled: transparent;
+      --color-accent-outlined-border-disabled: var(--fhi-color-surface-base);
+      --color-accent-outlined-disabled: var(--fhi-color-accent-text-subtle);
+
+      --color-accent-text-background: transparent;
+      --color-accent-text-border: transparent;
+      --color-accent-text: var(--fhi-color-accent-text-subtle);
+      --color-accent-text-background-hover: var(--fhi-color-accent-surface);
+      --color-accent-text-border-hover: var(--fhi-color-accent-surface);
+      --color-accent-text-hover: var(--fhi-color-accent-text);
+      --color-accent-text-background-active: var(
+        --fhi-color-accent-surface-hover
+      );
+      --color-accent-text-border-active: var(--fhi-color-accent-surface-hover);
+      --color-accent-text-active: var(--fhi-color-accent-text);
+      --color-accent-text-background-disabled: transparent;
+      --color-accent-text-border-disabled: transparent;
+      --color-accent-text-disabled: var(--fhi-color-accent-text);
+
+      --color-neutral-strong-background: var(--fhi-color-neutral-base);
+      --color-neutral-strong-border: var(--fhi-color-neutral-base);
+      --color-neutral-strong: var(--fhi-color-neutral-text-inverted);
+      --color-neutral-strong-background-hover: var(
+        --fhi-color-neutral-base-hover
+      );
+      --color-neutral-strong-border-hover: var(--fhi-color-neutral-base-hover);
+      --color-neutral-strong-hover: var(--fhi-color-neutral-text-inverted);
+      --color-neutral-strong-background-active: var(
+        --fhi-color-neutral-base-active
+      );
+      --color-neutral-strong-border-active: var(--fhi-color-neutral-base-hover);
+      --color-neutral-strong-active: var(--fhi-color-neutral-text-inverted);
+      --color-neutral-strong-background-disabled: var(--fhi-color-neutral-base);
+      --color-neutral-strong-border-disabled: var(--fhi-color-neutral-base);
+      --color-neutral-strong-disabled: var(--fhi-color-neutral-text-inverted);
+
+      --color-neutral-subtle-background: var(--fhi-color-neutral-surface);
+      --color-neutral-subtle-border: var(--fhi-color-neutral-surface);
+      --color-neutral-subtle: var(--fhi-color-neutral-text-subtle);
+      --color-neutral-subtle-background-hover: var(
+        --fhi-color-neutral-surface-hover
+      );
+      --color-neutral-subtle-border-hover: var(
+        --fhi-color-neutral-surface-hover
+      );
+      --color-neutral-subtle-hover: var(--fhi-color-neutral-text);
+      --color-neutral-subtle-background-active: var(
+        --fhi-color-neutral-surface-active
+      );
+      --color-neutral-subtle-border-active: var(
+        --fhi-color-neutral-surface-active
+      );
+      --color-neutral-subtle-active: var(--fhi-color-neutral-text);
+      --color-neutral-subtle-background-disabled: var(
+        --fhi-color-neutral-surface
+      );
+      --color-neutral-subtle-border-disabled: var(--fhi-color-neutral-surface);
+      --color-neutral-subtle-disabled: var(--fhi-color-neutral-text);
+
+      --color-neutral-outlined-background: transparent;
+      --color-neutral-outlined-border: var(--fhi-color-neutral-border);
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: trybern
body: ```suggestion
      --color-neutral-outlined-border: var(--fhi-color-neutral-border-subtle);
```
created_at: 2025-03-26T07:51:54Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,649 @@
+import { html, css, LitElement } from 'lit';
+import { customElement, property } from 'lit/decorators.js';
+
+export const FhiButtonSelector = 'fhi-button';
+
+@customElement(FhiButtonSelector)
+export class FhiButton extends LitElement {
+  @property({ type: String, reflect: true }) color:
+    | 'accent'
+    | 'neutral'
+    | 'danger' = 'accent';
+
+  @property({ type: String, reflect: true }) variant:
+    | 'strong'
+    | 'subtle'
+    | 'outlined'
+    | 'text' = 'strong';
+
+  @property({ type: String, reflect: true }) size:
+    | 'large'
+    | 'medium'
+    | 'small' = 'medium';
+
+  @property({ type: Boolean, reflect: true }) disabled = false;
+
+  @property({ type: String }) type: 'button' | 'submit' | 'reset' = 'submit';
+
+  private _formButton!: HTMLButtonElement;
+  private _form!: HTMLFormElement | null;
+
+  constructor() {
+    super();
+    this._stopClickLeak = this._stopClickLeak.bind(this);
+  }
+
+  override connectedCallback(): void {
+    if (!!super.connectedCallback) {
+      super.connectedCallback();
+    }
+
+    this._form = this.closest('form');
+  }
+
+  protected override firstUpdated(): void {
+    this._formButton = document.createElement('button');
+    this._formButton.addEventListener('click', this._stopClickLeak);
+    this.addEventListener('click', this._handleClick);
+  }
+
+  private _handleClick(event: MouseEvent): void {
+    if (
+      (this.type === 'submit' || this.type === 'reset') &&
+      this._form &&
+      !event.defaultPrevented
+    ) {
+      this._formButton.type = this.type;
+      this._form?.appendChild(this._formButton);
+      this._formButton.click();
+      this._form?.removeChild(this._formButton);
+    }
+  }
+
+  private _stopClickLeak(event: MouseEvent): void {
+    if (event.target === this._formButton) {
+      event.stopImmediatePropagation();
+    }
+  }
+
+  render() {
+    return html`<button ?disabled=${this.disabled} type=${this.type}>
+      <slot></slot>
+    </button>`;
+  }
+
+  static styles = css`
+    :host {
+      --dimension-border-radius: var(--fhi-border-radius-full);
+      --dimension-border-width: var(--fhi-dimension-border-width);
+      --typography-font-family: var(--fhi-font-family-roboto-flex);
+      --motion-transition: var(--fhi-motion-duration-quick)
+        var(--fhi-motion-ease-default);
+
+      --opacity-disabled: var(--fhi-opacity-disabled);
+
+      --typography-label-font-size-large: var(
+        --fhi-typography-label-large-font-size
+      );
+      --typography-label-font-size-medium: var(
+        --fhi-typography-label-medium-font-size
+      );
+      --typography-label-font-size-small: var(
+        --fhi-typography-label-small-font-size
+      );
+      --typography-label-font-weight-large: var(
+        --fhi-typography-label-font-weight-large
+      );
+      --typography-label-font-weight-medium: var(
+        --fhi-typography-label-medium-font-weight
+      );
+      --typography-label-font-weight-small: var(
+        --fhi-typography-label-small-font-weight
+      );
+      --typography-label-letter-spacing-large: var(
+        --fhi-typography-label-large-letter-spacing
+      );
+      --typography-label-letter-spacing-medium: var(
+        --fhi-typography-label-medium-letter-spacing
+      );
+      --typography-label-letter-spacing-small: var(
+        --fhi-typography-label-small-letter-spacing
+      );
+      --typography-label-line-height-large: var(
+        --fhi-typography-label-large-line-height
+      );
+      --typography-label-line-height-medium: var(
+        --fhi-typography-label-medium-line-height
+      );
+      --typography-label-line-height-small: var(
+        --fhi-typography-label-medium-line-height
+      );
+
+      --dimension-padding-small: calc(
+          var(--fhi-spacing-050) - var(--fhi-dimension-border-width)
+        )
+        calc(
+          var(--fhi-spacing-150) +
+            var(--fhi-spacing-050) - var(--fhi-dimension-border-width)
+        );
+      --dimension-padding-medium: calc(
+          var(--fhi-spacing-100) - var(--fhi-dimension-border-width)
+        )
+        calc(
+          var(--fhi-spacing-200) +
+            var(--fhi-spacing-050) - var(--fhi-dimension-border-width)
+        );
+      --dimension-padding-large: calc(
+          var(--fhi-spacing-200) - var(--fhi-dimension-border-width)
+        )
+        calc(
+          var(--fhi-spacing-300) +
+            var(--fhi-spacing-050) - var(--fhi-dimension-border-width)
+        );
+      --color-accent-strong-background: var(--fhi-color-accent-base);
+      --color-accent-strong-border: var(--fhi-color-accent-base);
+      --color-accent-strong: var(--fhi-color-accent-text-inverted);
+      --color-accent-strong-background-hover: var(
+        --fhi-color-accent-base-hover
+      );
+      --color-accent-strong-border-hover: var(--fhi-color-accent-base-hover);
+      --color-accent-strong-hover: var(--fhi-color-accent-text-inverted);
+      --color-accent-strong-background-active: var(
+        --fhi-color-accent-base-active
+      );
+      --color-accent-strong-border-active: var(--fhi-color-accent-base-hover);
+      --color-accent-strong-active: var(--fhi-color-accent-text-inverted);
+      --color-accent-strong-background-disabled: var(--fhi-color-accent-base);
+      --color-accent-strong-border-disabled: var(--fhi-color-accent-base);
+      --color-accent-strong-disabled: var(--fhi-color-accent-text-inverted);
+
+      --color-accent-subtle-background: var(--fhi-color-accent-surface);
+      --color-accent-subtle-border: var(--fhi-color-accent-surface);
+      --color-accent-subtle: var(--fhi-color-accent-text-subtle);
+      --color-accent-subtle-background-hover: var(
+        --fhi-color-accent-surface-hover
+      );
+      --color-accent-subtle-border-hover: var(--fhi-color-accent-surface-hover);
+      --color-accent-subtle-hover: var(--fhi-color-accent-text);
+      --color-accent-subtle-background-active: var(
+        --fhi-color-accent-surface-active
+      );
+      --color-accent-subtle-border-active: var(
+        --fhi-color-accent-surface-active
+      );
+      --color-accent-subtle-active: var(--fhi-color-accent-text);
+      --color-accent-subtle-background-disabled: var(
+        --fhi-color-accent-surface
+      );
+      --color-accent-subtle-border-disabled: var(--fhi-color-accent-surface);
+      --color-accent-subtle-disabled: var(--fhi-color-accent-text-subtle);
+
+      --color-accent-outlined-background: transparent;
+      --color-accent-outlined-border: var(--fhi-color-accent-border);
path: packages/fhi-designsystem/src/components/fhi-button/fhi-button.ts
user: login: trybern
body: ```suggestion
      --color-accent-outlined-border: var(--fhi-color-accent-border-subtle);
```
created_at: 2025-03-26T07:52:09Z
author_association: CONTRIBUTOR

PR comments:
user: login: trybern
created_at: 2025-03-17T10:29:43Z
body: Alt ser tipp-topp ut, @Masuso, men paddings på sidene samsvarer ikke med det som er satt opp i Figma.

For å gjøre Figma mindre kompleks, og mer brukervennlig, har vi en text-frame med 4px padding på siden, før knappens padding kommer inn med 16px ytterligere. Dette er for å balansere innholdet i knappen, når ikoner innføres.

Notatet på dette ble flyttet fra Button [og inn i egen Notater-side](https://www.figma.com/design/VgQG6XeEbFOmHIrxyAOACR/FHI-Designsystem?node-id=6687-17148&t=zz9C7BMakRB10GJc-11) for å holde presentasjonen ryddig, så kan være derfor det gikk litt i glemmeboka siden vi gikk gjennom designet første gang.

I praksis mangler alle knapper, med unntak av text, 4px padding på venstre og høyre side.
author_association: CONTRIBUTOR
user: login: dafn
created_at: 2025-03-19T14:07:22Z
body: small issue I found with the button example in storybook. When I reset the attributes, the button sometimes gets the wrong styling.

<img width="1159" alt="Skjermbilde 2025-03-19 kl  14 58 34" src="https://github.com/user-attachments/assets/75681f0d-ec4f-4b12-9900-942f3070fbd9" />
author_association: COLLABORATOR
user: login: Masuso
created_at: 2025-03-20T10:43:13Z
body: > small issue I found with the button example in storybook. When I reset the attributes, the button sometimes gets the wrong styling.
> 

Dett er en del av den rare oppførselen i storybook som jeg nevnte for litt siden. Det ser ut som at den letteste måten å fikse det på er å spesifisere defaultverdiene for color, variant og size. Men da vil de også komme med i kodeeksempelet, som vil si 
 
![image](https://github.com/user-attachments/assets/f01ea982-b8af-418e-a573-08602b7fb1f1)
 istendenfor 
![image](https://github.com/user-attachments/assets/94729b39-4231-4a3b-9e52-d92580d256fc)

@trybern @dafn 
author_association: CONTRIBUTOR
user: login: trybern
created_at: 2025-03-20T11:07:05Z
body: Det som virker til å skje er at default ikke settes på knappen igjen. Hvis jeg endrer størrelse i _Controls_ og deretter tilbakestiller kommer ikke `:host([size='medium']) button` som forventet. (Bilder på bunnen.) Endrer jeg alt, og deretter tilbakestiller, er det eneste knappen får det som er satt til `button`:

````
border-radius: var(--dimension-border-radius);
border: solid var(--dimension-border-width);
font-family: var(--typography-font-family);
transition: var(--motion-transition);
cursor: pointer;
````

Sammenligner vi med Pharos settes `:host([variant="primary"]) #button-element` på knappen inni shadow-root. 

Må tro det enten er en konfigurasjon i Storybook som må settes riktig eller at det er ett eller annet med strukturen vår.

Før noen endringer:
<img width="830" alt="Skjermbilde 2025-03-20 kl  11 58 41" src="https://github.com/user-attachments/assets/203dbee4-2721-4d2f-9009-f77893c6f29b" />

Etter å ha kun justert størrelse og deretter tilbakestilt:
<img width="845" alt="image" src="https://github.com/user-attachments/assets/55635a63-7422-4b5a-9783-d17291066c51" />

author_association: CONTRIBUTOR
user: login: trybern
created_at: 2025-03-21T12:36:22Z
body: Det er en rar oppførsel i Safari, der teksten markeres på dobbelttrykk (og alt annet ved trippeltrykk). Dette skjer ikke i Chromium.

<img width="1112" alt="image" src="https://github.com/user-attachments/assets/1ba748a7-ae8e-464c-99ff-b86c3de6b876" />

EDIT: Flyttet ut til egen sak #135 

author_association: CONTRIBUTOR