diff --git a/.travis.yml b/.travis.yml
index 6cc8953ee59..f639fa6aa01 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,6 +1,7 @@
+dist: xenial
language: node_js
node_js:
- - "--lts"
+ - "v12.6.0"
cache:
yarn: true
script:
diff --git a/packages/datepicker-react/README.md b/packages/datepicker-react/README.md
new file mode 100644
index 00000000000..c9ac1f71fc5
--- /dev/null
+++ b/packages/datepicker-react/README.md
@@ -0,0 +1,11 @@
+# `datepicker-react`
+
+> TODO: description
+
+## Usage
+
+```
+const datepickerReact = require('datepicker-react');
+
+// TODO: DEMONSTRATE API
+```
diff --git a/packages/datepicker-react/example/index.html b/packages/datepicker-react/example/index.html
new file mode 100644
index 00000000000..0503a13f8f1
--- /dev/null
+++ b/packages/datepicker-react/example/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+ Example datepicker
+
+
+
+
+
+
+
diff --git a/packages/datepicker-react/example/index.tsx b/packages/datepicker-react/example/index.tsx
new file mode 100644
index 00000000000..aa721ef70a0
--- /dev/null
+++ b/packages/datepicker-react/example/index.tsx
@@ -0,0 +1,39 @@
+//import "@fremtind/jkl-DatePicker/DatePicker.css";
+import "@fremtind/jkl-core/build/css/core.css";
+import React from "react";
+import ReactDOM from "react-dom";
+import { DatePicker } from "../src";
+import "@fremtind/jkl-datepicker/datepicker.scss";
+import "@fremtind/jkl-core/build/css/normalize.css";
+
+const App = () => (
+ <>
+
+
+
+
+
+
+
+ alert(`Date selected is ${date}`)} />
+
+
+ {
+ if (date.toDateString() === "Mon Sep 26 1988") {
+ alert("The greatest date is selected");
+ }
+ }}
+ />
+
+ >
+);
+
+ReactDOM.render(, document.getElementById("app"));
diff --git a/packages/datepicker-react/package.json b/packages/datepicker-react/package.json
new file mode 100644
index 00000000000..1d5c11d62b5
--- /dev/null
+++ b/packages/datepicker-react/package.json
@@ -0,0 +1,38 @@
+{
+ "name": "@fremtind/jkl-datepicker-react",
+ "version": "0.0.1",
+ "description": "datepicker",
+ "keywords": [
+ "datepicker"
+ ],
+ "directories": {
+ "lib": "build"
+ },
+ "files": [
+ "build"
+ ],
+ "license": "MIT",
+ "scripts": {
+ "build:types": "tsc -p tsconfig-for-declarations.json",
+ "build:scripts": "rollup --config ../../rollup.config.js",
+ "build": "yarn run build:scripts && yarn run build:types",
+ "test": "echo \"Error: run tests from root\" && exit 1",
+ "dev": "parcel example/index.html"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/fremtind/jokul.git"
+ },
+ "bugs": {
+ "url": "https://github.com/fremtind/jokul/issues"
+ },
+ "dependencies": {
+ "@fremtind/jkl-datepicker": "^0.0.1",
+ "@fremtind/jkl-text-input-react": "^0.0.1",
+ "@nrk/core-datepicker": "^3.0.5",
+ "@nrk/core-toggle": "^3.0.4"
+ },
+ "devDependencies": {
+ "@fremtind/jkl-core": "^0.0.1"
+ }
+}
diff --git a/packages/datepicker-react/src/DatePicker.test.tsx b/packages/datepicker-react/src/DatePicker.test.tsx
new file mode 100644
index 00000000000..36f7b2d9bb3
--- /dev/null
+++ b/packages/datepicker-react/src/DatePicker.test.tsx
@@ -0,0 +1,45 @@
+import React from "react";
+import { render, cleanup } from "@testing-library/react";
+import { DatePicker } from ".";
+
+beforeEach(cleanup);
+
+it("datepicker should render to dom with todays date as default", () => {
+ const { getByTestId } = render();
+
+ const today = new Date();
+
+ const date = getByTestId("jkl-datepicker-input");
+ expect(date).toHaveProperty("value", today.toLocaleDateString());
+});
+
+it("datepicker should render to dom with date in the past", () => {
+ const thePast = new Date(new Date().setFullYear(new Date().getFullYear() - 1));
+ const { getByTestId } = render();
+
+ const date = getByTestId("jkl-datepicker-input");
+ expect(date).toHaveProperty("value", thePast.toLocaleDateString());
+});
+
+it("datepicker should render to dom with date in the future", () => {
+ const theFuture = new Date(new Date().setFullYear(new Date().getFullYear() + 1));
+ const { getByTestId } = render();
+
+ const date = getByTestId("jkl-datepicker-input");
+ expect(date).toHaveProperty("value", theFuture.toLocaleDateString());
+});
+
+it("datepicker should render to dom with custom labels", () => {
+ const custom = {
+ label: "Select date",
+ yearLabel: "Year",
+ monthLabel: "Month",
+ };
+ const { getByLabelText } = render(
+ ,
+ );
+
+ const labels = [getByLabelText(custom.label), getByLabelText(custom.yearLabel), getByLabelText(custom.monthLabel)];
+
+ labels.forEach((label) => expect(label).toBeInTheDocument());
+});
diff --git a/packages/datepicker-react/src/DatePicker.tsx b/packages/datepicker-react/src/DatePicker.tsx
new file mode 100644
index 00000000000..cd8b1c3ea4d
--- /dev/null
+++ b/packages/datepicker-react/src/DatePicker.tsx
@@ -0,0 +1,69 @@
+import React, { useState, ChangeEvent } from "react";
+// @ts-ignore
+import CoreDatepicker from "@nrk/core-datepicker/jsx";
+// @ts-ignore
+import CoreToggle from "@nrk/core-toggle/jsx";
+import { TextField } from "@fremtind/jkl-text-input-react";
+
+interface ChangeDate {
+ date: Date;
+}
+
+interface Props {
+ label?: string;
+ monthLabel?: string;
+ yearLabel?: string;
+ initialDate?: Date;
+ onChange?: (date: Date) => void;
+ onlyFuture?: boolean;
+}
+
+export function DatePicker({
+ label = "Velg dato",
+ monthLabel = "Måned",
+ yearLabel = "År",
+ initialDate = new Date(),
+ onChange,
+ onlyFuture = true,
+}: Props) {
+ const [today] = useState(Date.now() - (Date.now() % 864e3));
+ const [date, setDate] = useState(initialDate);
+
+ const onDateChange = (e: ChangeEvent) => {
+ if (onChange) {
+ onChange(e.target.date);
+ }
+ setDate(e.target.date);
+ };
+
+ return (
+
+
+
+ date <= today : onlyFuture}
+ onDatepickerChange={onDateChange}
+ className="jkl-datepicker__calendar"
+ >
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/packages/datepicker-react/src/index.ts b/packages/datepicker-react/src/index.ts
new file mode 100644
index 00000000000..b0b3af5ed41
--- /dev/null
+++ b/packages/datepicker-react/src/index.ts
@@ -0,0 +1 @@
+export { DatePicker } from "./DatePicker";
diff --git a/packages/datepicker-react/tsconfig-for-declarations.json b/packages/datepicker-react/tsconfig-for-declarations.json
new file mode 100644
index 00000000000..742e5683436
--- /dev/null
+++ b/packages/datepicker-react/tsconfig-for-declarations.json
@@ -0,0 +1,8 @@
+{
+ "extends": "../../tsconfig-for-declarations.json",
+ "compilerOptions": {
+ "outDir": "./build",
+ "rootDir": "./src"
+ },
+ "include": ["./src"]
+}
diff --git a/packages/datepicker/README.md b/packages/datepicker/README.md
new file mode 100644
index 00000000000..ab9907b8cfe
--- /dev/null
+++ b/packages/datepicker/README.md
@@ -0,0 +1,11 @@
+# `datepicker`
+
+> TODO: description
+
+## Usage
+
+```
+const datepicker = require('datepicker');
+
+// TODO: DEMONSTRATE API
+```
diff --git a/packages/datepicker/datepicker.scss b/packages/datepicker/datepicker.scss
new file mode 100644
index 00000000000..7f7b379090f
--- /dev/null
+++ b/packages/datepicker/datepicker.scss
@@ -0,0 +1,70 @@
+@import "~@fremtind/jkl-core/build/scss/variables/spacing.scss";
+@import "~@fremtind/jkl-core/build/scss/variables/colors.scss";
+@import "~@fremtind/jkl-core/build/scss/typography/paragraphs.scss";
+@import "~@fremtind/jkl-core/build/scss/functions.scss";
+@import "~@fremtind/jkl-text-input/text-input.scss";
+
+$calendar-width: rem(402px);
+$calendar-box-size: rem(46px);
+
+.jkl-datepicker {
+ width: $calendar-width;
+ background-color: $snøhvit;
+
+ &__toggler {
+ border: none;
+ outline: none;
+ background-color: transparent;
+ text-align: left;
+ width: $calendar-width;
+ }
+ &__calendar {
+ display: flex;
+ justify-content: center;
+ flex-direction: column;
+ width: calc($calendar-width - $component-spacing--xl);
+ box-shadow: 0px rem(4px) rem(8px) rgba(0, 0, 0, 0.08);
+ padding: $component-spacing--xl;
+ &__header {
+ display: flex;
+ justify-content: center;
+ align-content: center;
+ &--year {
+ max-width: 30%;
+ }
+ &--month {
+ flex-grow: 2;
+ }
+ }
+
+ caption {
+ @extend .jkl-p;
+ padding-top: $component-spacing--xl;
+ text-transform: capitalize;
+ }
+ th {
+ font-weight: normal;
+ padding: $component-spacing--large 0;
+ }
+ button {
+ width: $calendar-box-size;
+ height: $calendar-box-size;
+ background-color: transparent;
+ border: $component-spacing--small solid $snøhvit;
+ border-radius: 50%;
+ outline: none;
+ transition: all 75ms ease-in;
+ &:hover {
+ background-color: $varm-fjellgrå;
+ color: $snøhvit;
+ }
+ &[aria-current="date"] {
+ background-color: $varde;
+ }
+ &[autofocus] {
+ background-color: $svart;
+ color: $snøhvit;
+ }
+ }
+ }
+}
diff --git a/packages/datepicker/package.json b/packages/datepicker/package.json
new file mode 100644
index 00000000000..2e55b148f9c
--- /dev/null
+++ b/packages/datepicker/package.json
@@ -0,0 +1,31 @@
+{
+ "name": "@fremtind/jkl-datepicker",
+ "version": "0.0.1",
+ "description": "datepicker style",
+ "keywords": [
+ "datepicker"
+ ],
+ "directories": {
+ "lib": "build"
+ },
+ "files": [
+ "build"
+ ],
+ "license": "MIT",
+ "scripts": {
+ "build": "node-sass . -o . --importer='../../node_modules/node-sass-tilde-importer'",
+ "test": "echo \"Error: run tests from root\" && exit 1",
+ "dev": "parcel example/index.html"
+ },
+ "dependencies": {
+ "@fremtind/jkl-core": "^0.0.1",
+ "@fremtind/jkl-text-input": "^0.0.1"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/fremtind/jokul.git"
+ },
+ "bugs": {
+ "url": "https://github.com/fremtind/jokul/issues"
+ }
+}
diff --git a/packages/text-input-react/src/TextField.tsx b/packages/text-input-react/src/TextField.tsx
index 49e3d985b0a..fd6c88a350a 100644
--- a/packages/text-input-react/src/TextField.tsx
+++ b/packages/text-input-react/src/TextField.tsx
@@ -2,24 +2,35 @@ import React, { ChangeEvent } from "react";
interface Props {
label: string;
- value: string;
- onChange: (value: ChangeEvent) => void;
- type?: "text" | "number" | "tel" | "password" | "email";
+ value?: string;
+ onChange?: (value: ChangeEvent) => void;
+ type?: "text" | "number" | "tel" | "password" | "email" | "year";
isInvalid?: boolean;
id?: string;
autoComplete?: string;
required?: boolean;
+ readOnly?: boolean;
+ className?: string;
}
-export const TextField = ({ type = "text", isInvalid = false, id, label, ...rest }: Props) => {
+export const TextField = ({
+ type = "text",
+ isInvalid = false,
+ readOnly = false,
+ id,
+ label,
+ className = "",
+ ...rest
+}: Props) => {
return (
-