Skip to content

Commit 7677fcc

Browse files
committed
feat: added more options to buttons, icons, textarea components
1 parent aa566c8 commit 7677fcc

File tree

6 files changed

+167
-52
lines changed

6 files changed

+167
-52
lines changed

resources/css/app.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,12 @@ table .actions {
125125
@apply relative w-full h-full max-w-2xl md:h-auto;
126126
pointer-events: auto;
127127
}
128+
.modal-content-container.modal-lg {
129+
@apply max-w-5xl;
130+
}
131+
.modal-content-container.modal-sm {
132+
@apply max-w-lg;
133+
}
128134
.modal-content {
129135
@apply relative bg-white rounded-lg shadow dark:bg-gray-700;
130136
}

resources/ts/Components/Button.svelte

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,47 @@
11
<script lang="ts">
22
import { createEventDispatcher } from 'svelte'
3-
import { Loading } from '.'
3+
import { Icon, Loading } from '.'
44
import { slide } from 'svelte/transition'
55
import { quadOut } from 'svelte/easing'
6-
const dispatch = createEventDispatcher()
6+
import { router } from '@inertiajs/svelte'
7+
8+
const dispatch = createEventDispatcher<{ click: void }>()
79
810
type ButtonSize = 'normal' | 'sm' | 'lg'
9-
type ButtonColor = 'primary' | 'secondary' | 'tertiary' | 'ghost'
11+
type ButtonColor = 'primary' | 'secondary' | 'tertiary' | 'danger' | 'ghost' | 'light'
1012
1113
export let size: ButtonSize = 'normal'
1214
export let color: ButtonColor = 'primary'
1315
export let block: string | boolean | undefined = undefined
1416
export let loading: boolean = false
17+
export let icon: string | undefined = undefined
18+
export let text: string | undefined = 'Click me'
19+
20+
export let route: string | undefined = undefined
21+
22+
function handleClick() {
23+
if (route !== undefined) {
24+
router.visit(route)
25+
return
26+
}
27+
dispatch('click')
28+
}
1529
</script>
1630

1731
<button
18-
class={`py-2 lg:py-3 px-4 lg:px-5 mx-1 flex gap-4 justify-center items-center text-sm lg:text-md ${color} btn-${size} ${
32+
class={`py-2 lg:py-3 px-4 lg:px-5 mx-1 flex gap-2 justify-center items-center text-sm lg:text-md ${color} btn-${size} ${
1933
block !== undefined ? 'w-full' : ''
2034
}`}
2135
{...$$restProps}
22-
on:click={() => dispatch('click')}
36+
on:click={handleClick}
2337
>
24-
<slot />
38+
{#if icon}
39+
<Icon name={icon} size="lg" />
40+
{/if}
41+
42+
<slot>
43+
{text}
44+
</slot>
2545

2646
{#if loading}
2747
<div transition:slide={{ axis: 'x', duration: 300, easing: quadOut }}>
@@ -54,10 +74,19 @@
5474
button.tertiary {
5575
@apply bg-gradient-to-r from-tertiary-500 via-tertiary-600 to-tertiary-700 hover:opacity-70;
5676
}
77+
button.danger {
78+
@apply border border-red-500 dark:border-red-500 shadow-sm font-medium rounded-md text-white dark:text-red-100 bg-red-500 dark:bg-red-800 hover:bg-red-900 dark:hover:bg-red-900 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500;
79+
}
5780
button.ghost {
58-
@apply border border-primary-700 dark:border-primary-300 text-primary-800 dark:text-primary-200;
81+
@apply border border-primary-700 dark:border-primary-300 text-primary-800 dark:text-primary-200 hover:bg-primary-100 dark:hover:bg-primary-700;
82+
}
83+
button.light {
84+
@apply border border-gray-300 dark:border-gray-600 shadow-sm font-medium rounded-md text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-900 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500;
5985
}
6086
button.btn-sm {
6187
@apply py-1 lg:py-2 px-2 lg:px-3;
6288
}
89+
button.btn-lg {
90+
@apply py-2.5 lg:py-3 px-3 lg:px-5;
91+
}
6392
</style>

resources/ts/Components/Icon.svelte

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,17 @@
22
export let name = 'bx bxs-pencil'
33
export let classes: string = ''
44
5+
type IconSize = 'n' | 'sm' | 'lg' | 'xl'
6+
export let size: IconSize = 'n'
7+
58
$: iconName = () => {
69
switch (name) {
10+
case 'email':
11+
return 'bx bx-envelope'
712
case 'edit':
813
return 'bx bx-pencil'
14+
case 'add':
15+
return 'bx bx-plus'
916
case 'delete':
1017
return 'bx bx-trash-alt'
1118
case 'email':
@@ -24,10 +31,39 @@
2431
return 'bx bx-up-arrow-alt'
2532
case 'arrow-down':
2633
return 'bx bx-down-arrow-alt'
34+
case 'waiting':
35+
return 'bx bx-time-five'
36+
case 'clear':
37+
return 'bx bx-x'
38+
case 'google':
39+
return 'bx bxl-google'
40+
case 'facebook':
41+
return 'bx bxl-facebook-circle'
42+
case 'verified':
43+
return 'bx bx-badge-check'
44+
case 'view':
45+
return 'bx bx-chevron-right'
46+
case 'reports':
47+
return 'bx bx-bar-chart-alt-2'
2748
}
2849
2950
return `bx bx-${name}`
3051
}
3152
</script>
3253

33-
<i class={iconName() + ' ' + classes} {...$$restProps} />
54+
<i class={`${iconName()} icon-${size} ${classes}`} {...$$restProps} />
55+
56+
<style lang="css">
57+
.icon-n {
58+
@apply text-[18px];
59+
}
60+
.icon-lg {
61+
@apply text-[22px];
62+
}
63+
.icon-xl {
64+
@apply text-[28px];
65+
}
66+
.icon-sm {
67+
@apply text-[14px];
68+
}
69+
</style>

resources/ts/Components/Input.svelte

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
<script lang="ts">
22
import { Icon } from '.'
3+
import { createEventDispatcher } from 'svelte'
4+
5+
enum Events {
6+
prefix,
7+
suffix,
8+
}
9+
const dispatch = createEventDispatcher<{ [key in keyof typeof Events]: undefined }>()
10+
const dispatchKeydown = createEventDispatcher<{ keydown: KeyboardEvent }>()
311
412
type InputColor = 'primary' | 'default'
513
@@ -13,10 +21,23 @@
1321
export let noMb: boolean | undefined = undefined // no margin bottom
1422
1523
export let prefixIcon: string | undefined = undefined
24+
export let suffixIcon: string | undefined = undefined
25+
26+
function handleKeydown(e: KeyboardEvent) {
27+
dispatchKeydown('keydown', e)
28+
}
29+
30+
function handlePrefixIconClick() {
31+
dispatch('prefix')
32+
}
33+
34+
function handleSuffixIconClick() {
35+
dispatch('suffix')
36+
}
1637
</script>
1738

1839
<div class:mb-6={!noMb}>
19-
<div class="flex {oneLine ? 'flex-row items-center' : 'flex-col'}">
40+
<div class="flex {oneLine ? 'flex-col md:flex-row items-center' : 'flex-col'}">
2041
<div class={oneLine ? 'w-full md:w-2/4 lg:w-1/4' : ''}>
2142
{#if label}
2243
<label for={name} class="block mb-2 text-sm font-medium label-{color}">{label}</label>
@@ -28,21 +49,30 @@
2849
<div class={oneLine ? 'w-full md:w-2/4 lg:w-3/4' : ''}>
2950
<div class="relative">
3051
{#if prefixIcon}
31-
<div class="absolute left-2 top-2.5">
52+
<div class="absolute left-2 top-2.5" on:click={handlePrefixIconClick}>
3253
<Icon name={prefixIcon} classes="icon-{color}" />
3354
</div>
3455
{/if}
3556

36-
<input
37-
{...$$restProps}
38-
id={name}
39-
{name}
40-
on:input
41-
bind:value
42-
class="input-{color} border text-sm rounded-lg block w-full p-2.5 {classes}"
43-
class:input-error={hasError}
44-
class:has-prefix-icon={!!prefixIcon}
45-
/>
57+
<slot>
58+
<input
59+
{...$$restProps}
60+
id={name}
61+
{name}
62+
on:input
63+
bind:value
64+
class="input-{color} border text-sm rounded-lg block w-full p-2.5 {classes}"
65+
class:input-error={hasError}
66+
class:has-prefix-icon={!!prefixIcon}
67+
on:keydown={handleKeydown}
68+
/>
69+
</slot>
70+
71+
{#if suffixIcon}
72+
<div class="absolute right-3 top-2.5 cursor-pointer" on:click={handleSuffixIconClick}>
73+
<Icon name={suffixIcon} classes="icon-{color}" />
74+
</div>
75+
{/if}
4676
</div>
4777
</div>
4878
</div>

resources/ts/Components/Textarea.svelte

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66
export let name: string
77
export let rows: number = 4
88
export let id: string = 'message'
9+
export let value: string | null = null
910
10-
let value = ''
11+
type InputColor = 'primary' | 'default'
12+
export let color: InputColor = 'primary'
1113
12-
const dispatch = createEventDispatcher()
13-
function handleInput() {
14-
dispatch('input', value)
14+
const dispatchKeydown = createEventDispatcher<{ keydown: KeyboardEvent }>()
15+
function handleKeydown(e: KeyboardEvent) {
16+
dispatchKeydown('keydown', e)
1517
}
1618
</script>
1719

@@ -24,10 +26,19 @@
2426
{name}
2527
id={name ?? id}
2628
{rows}
27-
class="bg-primary-50 dark:bg-primary-800 border border-primary-300 dark:border-primary-500 text-primary-900 dark:text-primary-100 text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full p-2.5 focus:outline-primary-500 placeholder:text-gray-400 dark:placeholder:text-primary-600"
29+
class="border text-sm rounded-lg block w-full p-2.5 textarea-{color}"
2830
{placeholder}
2931
bind:value
30-
on:input={handleInput}
32+
on:keydown={handleKeydown}
3133
{...$$props}
3234
/>
3335
</div>
36+
37+
<style lang="css">
38+
.textarea-primary {
39+
@apply bg-primary-50 dark:bg-primary-800 border-primary-300 dark:border-primary-500 text-primary-900 dark:text-primary-100 focus:ring-primary-500 focus:border-primary-500 focus:outline-primary-500 placeholder:text-gray-400 dark:placeholder:text-primary-600;
40+
}
41+
.textarea-default {
42+
@apply bg-gray-50 dark:bg-gray-800 border-gray-300 dark:border-gray-500 text-gray-900 dark:text-gray-100 focus:ring-gray-300 dark:focus:ring-gray-500 focus:border-gray-300 dark:focus:border-gray-600 focus:outline-gray-300 dark:focus:outline-gray-500 placeholder:text-gray-300 dark:placeholder:text-gray-600;
43+
}
44+
</style>

resources/ts/Pages/Auth/Login.svelte

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import { fly } from 'svelte/transition'
44
import { quintOut } from 'svelte/easing'
55
import { onMount } from 'svelte'
6-
import { Button, Input, Loading, Title } from '@/Components'
6+
import { Button, Icon, Input, Loading, Title } from '@/Components'
77
88
let ready = false
99
onMount(() => (ready = true))
@@ -68,38 +68,41 @@
6868
bind:value={$form.username}
6969
/>
7070

71-
<div class="my-3 relative">
72-
{#if showPassword}
73-
<Input
74-
name="username"
75-
hasError={$form.errors.username}
76-
type="text"
77-
placeholder="Password"
78-
bind:value={$form.password}
79-
/>
80-
{:else}
81-
<Input
82-
name="username"
83-
hasError={$form.errors.username}
84-
type="password"
85-
placeholder="Password"
86-
bind:value={$form.password}
87-
/>
88-
{/if}
71+
<Button color="ghost" block>
72+
<Icon name="bx bxs-magic-wand" size="lg" />
73+
Send Magic Login Link</Button
74+
>
8975

90-
<div class="absolute right-5 top-2">
91-
<button class="no-style" type="button" on:click={() => (showPassword = !showPassword)}>
92-
<i class="bx bx-lock text-lg" />
93-
</button>
94-
</div>
95-
</div>
76+
<p class="text-lg my-5 text-center">--OR--</p>
77+
78+
{#if showPassword}
79+
<Input
80+
name="username"
81+
hasError={$form.errors.username}
82+
type="text"
83+
placeholder="Password"
84+
bind:value={$form.password}
85+
suffixIcon="lock"
86+
on:suffix={() => (showPassword = !showPassword)}
87+
/>
88+
{:else}
89+
<Input
90+
name="username"
91+
hasError={$form.errors.username}
92+
type="password"
93+
placeholder="Password"
94+
bind:value={$form.password}
95+
suffixIcon="lock-open-alt"
96+
on:suffix={() => (showPassword = !showPassword)}
97+
/>
98+
{/if}
9699

97100
<!-- <label class="flex items-center space-x-2 my-3 ml-1">
98101
<input class="checkbox" type="checkbox" bind:checked={$form.remember} />
99102
<p>Remember Me</p>
100103
</label> -->
101104

102-
<Button type="submit" block disabled={$form.processing} loading={$form.processing}>Submit</Button>
105+
<Button type="submit" text="Login" block disabled={$form.processing} loading={$form.processing} />
103106
</form>
104107

105108
{#if canResetPassword}

0 commit comments

Comments
 (0)