mirror of https://github.com/Budibase/budibase.git
14 changed files with 344 additions and 12 deletions
@ -1,10 +1,31 @@ |
|||
<script> |
|||
import { getContext } from "svelte" |
|||
import ripple from "../Ripple.js" |
|||
|
|||
export let onClick = null |
|||
export let icon = "" |
|||
export let context = "" |
|||
|
|||
let cls = !!context ? `material-icons mdc-${context}__icon` : "material-icons" |
|||
|
|||
$: useRipple = onClick !== null |
|||
</script> |
|||
|
|||
<i class={cls}>{icon}</i> |
|||
{#if useRipple} |
|||
<div use:ripple> |
|||
<i on:click={onClick} class={cls}>{icon}</i> |
|||
</div> |
|||
{:else} |
|||
<i class={cls}>{icon}</i> |
|||
{/if} |
|||
|
|||
<style> |
|||
div { |
|||
border-radius: 50%; |
|||
padding-top: 2px; |
|||
width: fit-content; |
|||
height: fit-content; |
|||
cursor: pointer; |
|||
} |
|||
</style> |
|||
|
|||
@ -1,10 +1,185 @@ |
|||
<script> |
|||
import { Menu } from "../Menu" |
|||
import { Textfield } from "../Textfield" |
|||
import { onMount } from "svelte"; |
|||
import { |
|||
startOfMonth, |
|||
endOfMonth, |
|||
getDate, |
|||
getMonth, |
|||
getYear, |
|||
addMonths, |
|||
subMonths, |
|||
format |
|||
} from "date-fns"; |
|||
import { MDCMenu } from "@material/menu"; |
|||
import { Textfield } from "../Textfield"; |
|||
import Icon from "../Common/Icon.svelte"; |
|||
import ripple from "../Ripple.js"; |
|||
import { Body1, Body2, Caption } from "../Typography"; |
|||
|
|||
let open = false |
|||
debugger |
|||
let textFieldHeight = null; |
|||
let menu; |
|||
let instance; |
|||
|
|||
let daysArr = []; |
|||
let navDate = new Date(); |
|||
const weekdayMap = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]; |
|||
|
|||
export let date = new Date(); |
|||
export let open = true; |
|||
|
|||
onMount(() => { |
|||
if (!!menu) { |
|||
instance = new MDCMenu(menu); |
|||
instance.open = true; |
|||
instance.setFixedPostion = true; |
|||
} |
|||
}); |
|||
|
|||
function selectDate(dayOfMonth) { |
|||
let month = getMonth(navDate); |
|||
let year = getYear(navDate); |
|||
date = new Date(year, month, dayOfMonth); |
|||
} |
|||
|
|||
function addMonth() { |
|||
navDate = addMonths(navDate, 1); |
|||
} |
|||
|
|||
function subtractMonth() { |
|||
navDate = subMonths(navDate, 1); |
|||
} |
|||
|
|||
function openCalendar() { |
|||
instance.open = true; |
|||
} |
|||
|
|||
$: dateMonthEnds = endOfMonth(navDate).getDate(); |
|||
$: dateMonthBegins = startOfMonth(navDate).getDay(); |
|||
$: dayStart = dateMonthBegins + 1; //1 = sunday |
|||
$: monthAndYear = format(navDate, "MMMM y"); |
|||
$: selectedDate = format(date, "dd/MM/yyyy"); |
|||
$: dayOfSelectedDate = getDate(date); |
|||
$: for (let d = 1; d <= dateMonthEnds; d++) { |
|||
if (d === 1) { |
|||
daysArr = [d]; |
|||
} else { |
|||
daysArr = [...daysArr, d]; |
|||
} |
|||
} |
|||
$: rowRepeater = |
|||
dateMonthBegins > 5 && daysArr[daysArr.length - 1] > 30 ? 6 : 5; |
|||
$: sameMonthAndYear = |
|||
getMonth(date) === getMonth(navDate) && getYear(date) === getYear(navDate); |
|||
debugger; |
|||
</script> |
|||
|
|||
<Textfield label="Select Date" /> |
|||
<Menu {open} /> |
|||
<style> |
|||
.bbmd-menu { |
|||
width: 310px; |
|||
height: auto; |
|||
padding: 5px; |
|||
} |
|||
|
|||
.month-picker { |
|||
display: grid; |
|||
grid-template-columns: 20px 1fr 20px; |
|||
justify-content: center; |
|||
align-items: center; |
|||
} |
|||
|
|||
.month-picker > span { |
|||
text-align: center; |
|||
} |
|||
|
|||
.calendar-container { |
|||
display: grid; |
|||
height: 100%; |
|||
grid-template-rows: repeat(3, auto); |
|||
grid-gap: 5px; |
|||
} |
|||
|
|||
.calendar-container > div { |
|||
/* border: 1px solid red; */ |
|||
} |
|||
|
|||
.week-days { |
|||
display: grid; |
|||
grid-template-columns: repeat(7, 1fr); |
|||
} |
|||
|
|||
.day-picker { |
|||
display: grid; |
|||
grid-template-columns: repeat(7, 1fr); |
|||
} |
|||
|
|||
.centreText { |
|||
text-align: center; |
|||
} |
|||
|
|||
span { |
|||
margin: auto; |
|||
} |
|||
</style> |
|||
|
|||
<!-- |
|||
TODO: Add trailing icon button on textfield that is clickable |
|||
TODO: Add transition effects to toggling of calendar |
|||
TODO: Bug - August 2020 has too many rows. find out why |
|||
TODO: Bug - make out transition of date bg colour instantaneous |
|||
--> |
|||
<div class="mdc-menu-surface--anchor"> |
|||
<Textfield |
|||
bind:tfHeight={textFieldHeight} |
|||
value={selectedDate} |
|||
trailingIcon={true} |
|||
useIconButton={true} |
|||
iconButtonClick={openCalendar} |
|||
icon="calendar_today" |
|||
label="Select Date" /> |
|||
|
|||
<div |
|||
bind:this={menu} |
|||
class="mdc-menu mdc-menu-surface bbmd-menu" |
|||
style={`margin-top: ${textFieldHeight + 15}px`}> |
|||
<div class="calendar-container"> |
|||
<div class="month-picker"> |
|||
<span> |
|||
<Icon icon="chevron_left" onClick={subtractMonth} /> |
|||
</span> |
|||
<div class="centreText"> |
|||
<Body1 text={monthAndYear} /> |
|||
</div> |
|||
<span> |
|||
<Icon icon="chevron_right" onClick={addMonth} /> |
|||
</span> |
|||
</div> |
|||
<div class="week-days"> |
|||
{#each weekdayMap as day, i} |
|||
<div class="centreText"> |
|||
<Caption text={day} /> |
|||
</div> |
|||
{/each} |
|||
</div> |
|||
<div |
|||
class="day-picker" |
|||
style={`grid-template-rows: repeat(${rowRepeater}, 40px)`}> |
|||
{#each daysArr as day, i} |
|||
<div |
|||
use:ripple |
|||
on:click={() => selectDate(day)} |
|||
class={`bbmd-day ${dayOfSelectedDate === day && sameMonthAndYear ? 'selected' : ''}`}> |
|||
{#if i === 0} |
|||
<div style={`grid-column-start: ${dateMonthBegins}`}> |
|||
<Body2 text={day} /> |
|||
</div> |
|||
{:else} |
|||
<Body2 text={day} /> |
|||
{/if} |
|||
</div> |
|||
{/each} |
|||
</div> |
|||
</div> |
|||
|
|||
<ul class="mdc-list" role="menu" /> |
|||
</div> |
|||
</div> |
|||
|
|||
@ -0,0 +1,15 @@ |
|||
@import "@material/ripple/mdc-ripple.scss"; |
|||
@import "@material/theme/mixins"; |
|||
|
|||
.bbmd-day { |
|||
transition: background-color 0.5s ease-in; |
|||
display: flex; |
|||
border-radius: 50%; |
|||
justify-content: center; |
|||
align-items: center; |
|||
cursor: pointer; |
|||
} |
|||
.selected { |
|||
@include mdc-theme-prop(background-color, primary); |
|||
@include mdc-theme-prop(color, on-primary); |
|||
} |
|||
@ -1 +1,2 @@ |
|||
export { default as DatePicker } from "./DatePicker.svelte" |
|||
import "./_style.scss"; |
|||
export { default as DatePicker } from "./DatePicker.svelte"; |
|||
|
|||
@ -0,0 +1,40 @@ |
|||
<script> |
|||
import ripple from "../Ripple.js"; |
|||
import ClassBuilder from "../ClassBuilder.js"; |
|||
|
|||
const cb = new ClassBuilder("icon-button"); |
|||
|
|||
export let onClick = () => {}; |
|||
export let disabled = false; |
|||
export let href = ""; |
|||
export let icon = ""; |
|||
export let onIcon = ""; //on state icon for toggle button |
|||
export let size = "medium"; |
|||
|
|||
$: isToggleButton = !!icon && !!onIcon; |
|||
$: useLinkButton = !!href; |
|||
|
|||
$: customs = { size }; |
|||
$: props = { customs, extras: ["material-icons"] }; |
|||
$: iconBtnClass = cb.build({ props }); |
|||
</script> |
|||
|
|||
{#if useLinkButton} |
|||
<a on:click={onClick} class={iconBtnClass} {href} {disabled}> |
|||
{#if isToggleButton} |
|||
<i class="material-icons mdc-icon-button__icon mdc-icon-button__icon--on"> |
|||
{onIcon} |
|||
</i> |
|||
<i class="material-icons mdc-icon-button__icon">{icon}</i> |
|||
{:else}{icon}{/if} |
|||
</a> |
|||
{:else} |
|||
<button on:click={onClick} use:ripple class={iconBtnClass} {disabled}> |
|||
{#if isToggleButton} |
|||
<i class="material-icons mdc-icon-button__icon mdc-icon-button__icon--on"> |
|||
{onIcon} |
|||
</i> |
|||
<i class="material-icons mdc-icon-button__icon">{icon}</i> |
|||
{:else}{icon}{/if} |
|||
</button> |
|||
{/if} |
|||
@ -0,0 +1,13 @@ |
|||
@import "@material/icon-button/mdc-icon-button"; |
|||
|
|||
.bbmd-mdc-icon-button--size-large { |
|||
@include mdc-icon-button-icon-size(24px); |
|||
} |
|||
|
|||
.bbmd-mdc-icon-button--size-medium { |
|||
@include mdc-icon-button-icon-size(20px); |
|||
} |
|||
|
|||
.bbmd-mdc-icon-button--size-small { |
|||
@include mdc-icon-button-icon-size(16px); |
|||
} |
|||
@ -0,0 +1,2 @@ |
|||
import "./_style.scss"; |
|||
export { default as IconButton } from "./IconButton.svelte"; |
|||
Loading…
Reference in new issue