Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add initial forms components #299

Open
wants to merge 17 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions src/lib/components/forms/files-input.svelte
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is missing Storybook stories, if you need any help let me know!

Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<script>
let files = null;

$: () => {
if (files) {
console.log(files);
for (const file of files) {
console.log(`${file.name}: ${file.size} bytes`);
}
}
};
Comment on lines +4 to +11
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't forget to remove when you're done :)

</script>

<div class="flex items-center space-x-4">
<label
for="file-upload"
class="muted-red cursor-pointer rounded-lg px-4 py-2 text-white hover:bg-red-600"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The button differs a bit currently from the mockups:
image
We should add the red background color to the button and maybe make that color a bit darker on hover?

>
Selecionar ficheiro
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be an input to the component so that we can place whatever text here!

</label>

<input id="file-upload" multiple type="file" bind:files class="hidden" />

{#if files}
{#each Array.from(files) as file}
<div class="rounded-lg bg-taupe-200 px-4 py-2 text-rose-950">
<p>{file.name}</p>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm it would be useful if each file could have a little X to remove just that file, would that be doable?

</div>
{/each}
{/if}
</div>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd change this to be in the same storybook folder as the rest, for example in Atoms/Forms/Label Input

File renamed without changes.
18 changes: 18 additions & 0 deletions src/lib/components/forms/picture-input.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import PictureInput from './picture-input.svelte';

export default {
title: 'Atoms/Forms/Picture Input',
component: PictureInput,
argTypes: {
text: { control: 'text' }
},
parameters: {
layout: 'centered'
}
};

export const Example = {
tomas-sucena marked this conversation as resolved.
Show resolved Hide resolved
args: {
text: 'Adicionar logo'
}
};
74 changes: 74 additions & 0 deletions src/lib/components/forms/picture-input.svelte
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd also try to see if you can line up the text with the *, it looks a bit off-center currently!
image

Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<script lang="ts">
import Icon from '$lib/components/icons/icon.svelte';
import Icons from '$lib/components/icons/icons';

export let text: string;
let avatar, fileinput;
tomas-sucena marked this conversation as resolved.
Show resolved Hide resolved

const onFileSelected = (e) => {
let image = e.target.files[0];
let reader = new FileReader();
reader.readAsDataURL(image);
reader.onload = (e) => {
avatar = e.target.result;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
avatar = e.target.result;
if (e.target?.result) {
avatar = e.target.result.toString();
}

My IDE nagged me about this because e.target might be null in error cases ;p

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, this shows no error if the file uploaded is of the wrong type, we should add that

};
};
</script>

<div id="app" class="flex flex-col items-center justify-center">
{#if avatar}
<div class="relative flex h-[200px] w-[200px] overflow-hidden rounded-md">
<img class="h-[200px] w-[200px] object-cover" src={avatar} alt="Avatar" />
<button
type="button"
aria-label="Change Avatar"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because this is gonna be a reusable component, I'd recommend changing the aria-label and alts to use the text you receive or use more general terms like upload image :) For the same reason I'd also rename this to image-input and change references to avatarto image as well, but let me know what you think!

class="absolute bottom-0 right-0 m-2 flex h-[15%] w-[15%] cursor-pointer items-center justify-center rounded-md bg-rose-950"
on:click={() => {
fileinput.click();
}}
on:keydown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
fileinput.click();
}
}}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These bindings are not working for me, are they for you?

>
<Icon src={Icons.Edit} color="white" size="70%" />
</button>
<input
style="display:none"
type="file"
accept=".jpg, .jpeg, .png"
on:change={(e) => onFileSelected(e)}
bind:this={fileinput}
/>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The button and input are repeated and can be moved to outside the if statement

</div>
{:else}
<div
class="relative flex h-[200px] w-[200px] items-center justify-center rounded-md bg-muted-red-400 text-center"
>
<p class="font-medium text-white">{text}<span class="text-4xl">*</span></p>
<button
type="button"
aria-label="Change Avatar"
class="absolute bottom-0 right-0 m-2 flex h-[15%] w-[15%] cursor-pointer items-center justify-center rounded-md bg-rose-950"
on:click={() => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be more intuitive and more accessible on mobile if you could click anywhere on the square, not just on the edit button!

fileinput.click();
}}
on:keydown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
fileinput.click();
}
}}
>
<Icon src={Icons.Edit} color="white" size="60%" />
</button>
<input
style="display:none"
type="file"
accept=".jpg, .jpeg, .png"
on:change={(e) => onFileSelected(e)}
bind:this={fileinput}
/>
</div>
{/if}
</div>
18 changes: 18 additions & 0 deletions src/lib/components/forms/radio-buttons.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import RadioButtons from './radio-buttons.svelte';

export default {
title: 'Atoms/Forms/Radio Buttons',
component: RadioButtons,
argTypes: {
options: { control: 'array' }
},
parameters: {
layout: 'centered'
}
};

export const Example = {
tomas-sucena marked this conversation as resolved.
Show resolved Hide resolved
args: {
options: ['English', 'Spanish']
}
};
29 changes: 29 additions & 0 deletions src/lib/components/forms/radio-buttons.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<script lang="ts">
export let options: string[];
let selectedOption: string;
</script>

<div>
tomas-sucena marked this conversation as resolved.
Show resolved Hide resolved
{#each options as option}
<input
id="radio-{option}"
class="radio-button hidden text-center"
type="radio"
bind:group={selectedOption}
value={option}
/>
<label
class="m-1 justify-self-start rounded-lg bg-taupe-200 px-5 py-1 text-rose-950"
for="radio-{option}"
>
tomas-sucena marked this conversation as resolved.
Show resolved Hide resolved
{option}
</label>
{/each}
</div>

<style>
.radio-button:checked + label {
background-color: theme('colors.muted-red.400');
color: theme('colors.taupe.100');
}
</style>
4 changes: 3 additions & 1 deletion src/lib/components/icons/icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from 'svelte-icons-pack/fa';
import { BiMap } from 'svelte-icons-pack/bi';
import { IoMail, IoClose, IoEye, IoEyeOff } from 'svelte-icons-pack/io';
import { FiEdit2 } from 'svelte-icons-pack/fi';

const Icons = {
Instagram: FaBrandsInstagram,
Expand All @@ -24,7 +25,8 @@ const Icons = {
Globe: FaSolidGlobe,
Pin: BiMap,
Visible: IoEye,
Hidden: IoEyeOff
Hidden: IoEyeOff,
Edit: FiEdit2
};

export default Icons;
2 changes: 1 addition & 1 deletion src/routes/(app)/contacts/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts">
import { Icon } from 'svelte-icons-pack';
import Graph from './_components/graph.svelte';
import LabelInput from '@/lib/components/icons/label-input.svelte';
import LabelInput from '@/lib/components/forms/label-input.svelte';
import Icons from '$lib/components/icons/icons';
</script>

Expand Down