Skip to content

Commit

Permalink
Merge pull request #305 from matematikk-mooc/Therese-Persen_KURSP-874…
Browse files Browse the repository at this point in the history
…-basic-form-elementer-og-login-form

create form elements and login form
  • Loading branch information
manilpit authored Sep 25, 2023
2 parents 18787a5 + 9cf17d4 commit 9692a64
Show file tree
Hide file tree
Showing 17 changed files with 651 additions and 12 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"terser-webpack-plugin": "^5.3.9",
"vue": "^3.3.4",
"vue-loader": "^17.2.2",
"vee-validate": "^4.5.8",
"vue-material-design-icons": "^5.2.0",
"vue3-icon": "^2.1.0",
"webpack": "^5.88.2",
Expand Down
6 changes: 4 additions & 2 deletions src/vue/.storybook/main.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/** @type { import('@storybook/vue3-webpack5').StorybookConfig } */
const webpack = require("webpack");
const path = require("path");
const config = {

module.exports = {
stories: ["../**/*.stories.@(js|jsx|mjs|ts|tsx)"],
addons: [
"storybook-addon-sass-postcss",
Expand All @@ -18,13 +19,14 @@ const config = {
},
staticDirs: [path.resolve(__dirname, "../assets")],
webpackFinal: async (config) => {
// Define global constants that can be accessed in your stories
config.plugins.push(
new webpack.DefinePlugin({
SERVER: JSON.stringify("http://localhost:6006/"),
})
);

return config;
},
};

export default config;
19 changes: 10 additions & 9 deletions src/vue/.storybook/preview-head.html
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
<!-- .storybook/preview-head.html -->

<!-- Pull in static files served from your Static directory or the internet -->
<!-- Example: `main.js|ts` is configured with staticDirs: ['../public'] and your font is located in the `fonts` directory inside your `public` directory -->
<link rel="preload" href="/fonts/MontserratBold.woff2" />
<link rel="preload" href="/fonts/MontserratRegular.woff2" />
<link rel="preload" href="/fonts/MontserratMedium.woff2" />
<!-- Preload fonts for better performance -->
<link rel="preload" href="/fonts/MontserratBold.woff2" as="font" type="font/woff2" crossorigin="anonymous" />
<link rel="preload" href="/fonts/MontserratRegular.woff2" as="font" type="font/woff2" crossorigin="anonymous" />
<link rel="preload" href="/fonts/MontserratMedium.woff2" as="font" type="font/woff2" crossorigin="anonymous" />

<link rel="preload" href="/fonts/RobotoBold.woff2" />
<link rel="preload" href="/fonts/RobotoRegular.woff2" />
<link rel="preload" href="/fonts/RobotoMedium.woff2" />
<link rel="preload" href="/fonts/RobotoBold.woff2" as="font" type="font/woff2" crossorigin="anonymous" />
<link rel="preload" href="/fonts/RobotoRegular.woff2" as="font" type="font/woff2" crossorigin="anonymous" />
<link rel="preload" href="/fonts/RobotoMedium.woff2" as="font" type="font/woff2" crossorigin="anonymous" />

<!-- Include custom fonts stylesheet -->
<link rel="stylesheet" href="/fonts.css">
72 changes: 72 additions & 0 deletions src/vue/assets/fonts.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/* Montserrat Font Family */
@font-face {
font-family: 'Montserrat';
font-style: normal;
font-stretch: normal;
font-family: 'Montserrat';
src: url('/fonts/MontserratRegular.woff2') format('woff2'),
url('/fonts/MontserratRegular.woff') format('woff');
font-weight: 400;
}

@font-face {
font-family: 'Montserrat';
src: url('/fonts/MontserratRegular.woff2') format('woff2'),
url('/fonts/MontserratRegular.woff') format('woff');
font-weight: 400;
}

@font-face {
font-family: 'Montserrat';
src: url('/fonts/MontserratMedium.woff2') format('woff2'),
url('/fonts/MontserratMedium.woff') format('woff');
font-weight: 500;
}

@font-face {
font-family: 'Montserrat';
src: url('/fonts/MontserratSemiBold.woff2') format('woff2'),
url('/fonts/MontserratSemiBold.woff') format('woff');
font-weight: 600;
}

@font-face {
font-family: 'Montserrat';
src: url('/fonts/MontserratBold.woff2') format('woff2'),
url('/fonts/MontserratBold.woff') format('woff');
font-weight: 700;
}

/* Roboto Font Family */
@font-face {
font-family: 'Roboto';
font-style: normal;
}

@font-face {
font-family: 'Roboto';
src: url('/fonts/RobotoRegular.woff2') format('woff2'),
url('/fonts/RobotoRegular.woff') format('woff');
font-weight: normal;
}

@font-face {
font-family: 'Roboto';
src: url('/fonts/RobotoMedium.woff2') format('woff2'),
url('/fonts/RobotoMedium.woff') format('woff');
font-weight: 500;
}

@font-face {
font-family: 'RobotoBold';
src: url('/fonts/RobotoBold.woff2') format('woff2'),
url('/fonts/RobotoBold.woff') format('woff');
font-weight: 700;
}

/* Body */
body {
font-family: 'Roboto', sans-serif;
}


2 changes: 1 addition & 1 deletion src/vue/components/Button.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<button
:class="[
{ btn: true },
{ 'btn--filled': type === undefined || type === 'filled' },
{ 'btn--filled': type === undefined || type === 'submit' || type === 'filled' },
{ 'btn--outlined': type === 'outlined' },
{ 'btn--sm': size === 'sm' },
{ 'btn--md': size === undefined || size === 'md' },
Expand Down
24 changes: 24 additions & 0 deletions src/vue/components/checkbox-input/CheckboxInput.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import CheckboxInput from "./CheckboxInput.vue";

export default {
title: "Components/CheckboxInput",
component: CheckboxInput,
argTypes: {
label: { control: "text" },
name: { control: "text" },
},
};

const Template = (args) => ({
components: { CheckboxInput },
setup() {
return { args };
},
template: '<CheckboxInput v-bind="args"></CheckboxInput>',
});

export const Default = Template.bind({});
Default.args = {
label: "Checkbox label",
name: "staySignedIn",
};
95 changes: 95 additions & 0 deletions src/vue/components/checkbox-input/CheckboxInput.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<template>
<label class="checkbox-input" :for="name">
<input :id="name" v-model="modelValue" type="checkbox" class="checkbox-input__checkbox" />
<span class="checkbox-input__label">
{{ label }}
</span>
</label>
</template>

<script>
import { ref, watch } from 'vue'
import { useField } from 'vee-validate'
export default {
name: 'CheckboxInput',
props: {
name: String,
label: String,
},
setup() {
const modelValue = ref(false)
const { value: fieldValue } = useField(props.name)
watch(modelValue, (newValue) => {
console.log('model value is', modelValue)
fieldValue.value = newValue
})
return {
modelValue,
}
},
}
</script>

<style lang="scss">
.checkbox-input {
display: flex;
justify-content: flex-start;
margin-bottom: 0.5rem;
margin-top: 0.5rem;
&__label {
font-size: 0.85rem;
/* Custom checkbox styling */
input[type="checkbox"] {
/* Hide the default checkbox input */
position: absolute;
opacity: 0;
/* Style the checkmark container */
&~.checkmark {
position: relative;
width: 1rem;
/* Increase the width for a larger checkbox */
height: 1rem;
/* Increase the height for a larger checkbox */
background-color: #ffffff;
border-radius: 0.25rem;
border: 0.0625rem solid #bfbfbf;
/* Style the checkmark indicator (hidden when unchecked) */
&:after {
content: "";
position: absolute;
display: none;
}
}
/* Show the checkmark when checked */
&:checked~.checkmark:after {
display: block;
}
}
/* Style the checkmark/indicator */
input[type="checkbox"]~.checkmark:after {
content: "";
position: absolute;
left: 0.5rem;
/* Adjust the position of the checkmark */
top: 0.9rem;
/* Adjust the position of the checkmark */
width: .5rem;
height: 1rem;
border: solid white;
border-width: 0 0.25rem 0.25rem 0;
/* Adjust the size of the checkmark */
transform: rotate(45deg);
}
}
}
</style>


25 changes: 25 additions & 0 deletions src/vue/components/link/Link.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { defineComponent } from "vue";

import Link from "./Link.vue"; // Import your Link component

export default {
title: "Components/Link",
component: Link,
argTypes: {
url: { control: "text" },
},
};

const Template = (args) =>
defineComponent({
components: { Link },
setup() {
return { args };
},
template: '<Link v-bind="args">Gå til siden</Link>',
});

export const Default = Template.bind({});
Default.args = {
url: "https://example.com",
};
35 changes: 35 additions & 0 deletions src/vue/components/link/Link.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<template>
<a :href="url" class="link">
<slot></slot>
</a>
</template>
<script>
import { defineComponent } from "vue";
export default defineComponent({
props: {
url: String,
},
});
</script>

<style lang="scss">
@import "../../design/semantic-colors";
.link {
color: black;
cursor: pointer;
&__text {
color: #000;
font-family: Montserrat;
font-size: 0.85rem;
font-style: normal;
font-weight: 400;
line-height: normal;
}
&:hover {
text-decoration: underline;
color: map-get($semantic-colors, hover);
}
}
</style>
24 changes: 24 additions & 0 deletions src/vue/components/login-form/LoginForm.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { defineComponent } from "vue";
import LoginForm from "./LoginForm.vue";

export default {
title: "Components/LoginForm",
component: LoginForm,
};

const Template = (args) =>
defineComponent({
components: { LoginForm },
setup() {
return args;
},
template:
'<div style="max-width:700px;display:flex;alignContent:center;justifyContent:center;padding:30px"><LoginForm v-bind="args" /></div>',
});

export const Default = Template.bind({});
Default.args = {
email: "",
password: "",
stayLoggedIn: false,
};
Loading

0 comments on commit 9692a64

Please sign in to comment.