Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
5 changes: 5 additions & 0 deletions .changeset/clever-avocados-hope.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"svelte-ux": minor
---

Add ability to set a default values for labelPlacement and variant props
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,19 @@
import '../app.postcss';

settings({
classes: {
AppBar: 'bg-primary text-white shadow-md',
components: {
AppBar: {
classes: 'bg-primary text-white shadow-md'
},
AppLayout: {
nav: 'bg-neutral-800'
classes: {
nav: 'bg-neutral-800'
}
},
NavItem: {
root: 'text-sm text-gray-400 pl-6 py-2 hover:text-white hover:bg-gray-300/10 [&:where(.is-active)]:text-sky-400 [&:where(.is-active)]:bg-gray-500/10'
classes: {
root: 'text-sm text-gray-400 pl-6 py-2 hover:text-white hover:bg-gray-300/10 [&:where(.is-active)]:text-sky-400 [&:where(.is-active)]:bg-gray-500/10'
}
}
}
});
Expand Down
32 changes: 13 additions & 19 deletions packages/svelte-ux/src/lib/components/Button.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@
import { cls } from '../utils/styles';
import { multi } from '../actions/multi';
import type { Actions } from '../actions/multi';
import type { ThemeColors } from '$lib/types';
import { getComponentClasses } from './theme';
import type { ButtonColor, ButtonSize } from '$lib/types';
import { getButtonGroup } from './ButtonGroup.svelte';
import { asIconData, type IconInput } from '$lib/utils/icons';
import type { ButtonRounded, ButtonVariant } from '$lib/types';
import { getComponentSettings } from './settings';

const { classes: settingsClasses, defaults } = getComponentSettings('Button');

export let type: 'button' | 'submit' | 'reset' = 'button';
export let href: string | undefined = undefined;
Expand All @@ -21,33 +24,24 @@

export let loading: boolean = false;
export let disabled: boolean = false;
export let rounded: boolean | 'full' | undefined = undefined; // default in reactive groupContext below
export let variant:
| 'default'
| 'outline'
| 'fill'
| 'fill-outline'
| 'fill-light'
| 'text'
| 'none'
| undefined = undefined; // default in reactive groupContext below
export let size: 'sm' | 'md' | 'lg' | undefined = undefined; // default in reactive groupContext below
export let color: ThemeColors | 'default' | undefined = undefined; // default in reactive groupContext below
export let rounded: ButtonRounded | undefined = undefined; // default in reactive groupContext below
export let variant: ButtonVariant | undefined = undefined; // default in reactive groupContext below
export let size: ButtonSize | undefined = undefined; // default in reactive groupContext below
export let color: ButtonColor | undefined = undefined; // default in reactive groupContext below

/** @type {{root?: string, icon?: string, loading?: string}} */
export let classes: {
root?: string;
icon?: string;
loading?: string;
} = {};
const settingsClasses = getComponentClasses('Button');

// Override default from `ButtonGroup` if set
const groupContext = getButtonGroup();
$: variant = variant ?? groupContext?.variant ?? 'default';
$: size = size ?? groupContext?.size ?? 'md';
$: color = color ?? groupContext?.color ?? 'default';
$: rounded = rounded ?? groupContext?.rounded ?? (iconOnly ? 'full' : true);
$: variant = variant ?? groupContext?.variant ?? defaults.variant ?? 'default';
$: size = size ?? groupContext?.size ?? defaults.size ?? 'md';
$: color = color ?? groupContext?.color ?? defaults.color ?? 'default';
$: rounded = rounded ?? groupContext?.rounded ?? defaults.rounded ?? (iconOnly ? 'full' : true);

$: _class = cls(
'Button',
Expand Down
35 changes: 13 additions & 22 deletions packages/svelte-ux/src/lib/components/ButtonGroup.svelte
Original file line number Diff line number Diff line change
@@ -1,23 +1,14 @@
<script lang="ts" context="module">
import { type ComponentProps, setContext, getContext } from 'svelte';
import type Button from './Button.svelte';
import type { ThemeColors } from '$lib/types';
import type { ButtonColor, ButtonSize } from '$lib/types';
import type { ButtonRounded, ButtonVariant } from '$lib/types';

// TODO: Use `ButtonProps['...']` if can work around circular reference (Button <-> ButtonGroup)
type ButtonProps = ComponentProps<Button>;
type ButtonGroupContext = {
variant:
| 'default'
| 'outline'
| 'fill'
| 'fill-outline'
| 'fill-light'
| 'text'
| 'none'
| undefined; // ButtonProps['variant'];
size: 'sm' | 'md' | 'lg' | undefined; //ButtonProps['size'];
color: ThemeColors | 'default' | undefined; //ButtonProps['color'];
rounded: boolean | 'full' | undefined; // ButtonProps['rounded']
variant: ButtonVariant | undefined;
size: ButtonSize | undefined;
color: ButtonColor | undefined;
rounded: ButtonRounded | undefined;
};

const buttonGroupKey = Symbol();
Expand All @@ -33,15 +24,15 @@

<script lang="ts">
import { cls } from '../utils/styles';
import { getComponentClasses } from './theme';
import { getComponentSettings } from './settings';

export let variant: ComponentProps<Button>['variant'] = undefined;
export let size: ComponentProps<Button>['size'] | undefined = undefined;
export let color: ComponentProps<Button>['color'] | undefined = undefined;
export let rounded: ComponentProps<Button>['rounded'] | undefined = undefined;
export let disabled: boolean = false;
const { classes: settingsClasses, defaults } = getComponentSettings('ButtonGroup');

const settingsClasses = getComponentClasses('ButtonGroup');
export let variant: ComponentProps<Button>['variant'] = defaults.variant;
export let size: ComponentProps<Button>['size'] | undefined = defaults.size;
export let color: ComponentProps<Button>['color'] | undefined = defaults.color;
export let rounded: ComponentProps<Button>['rounded'] | undefined = defaults.rounded;
export let disabled: boolean = false;

$: _class = cls(
'ButtonGroup',
Expand Down
8 changes: 5 additions & 3 deletions packages/svelte-ux/src/lib/components/CopyButton.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,24 @@

import { cls } from '../utils/styles';
import Button from './Button.svelte';
import { getComponentClasses } from './theme';
import { getComponentSettings } from './settings';
import { slide } from 'svelte/transition';

const { classes: settingsClasses, defaults } = getComponentSettings('CopyButton');

export let value: string;

let showMessage = false;
$: if (showMessage) {
setTimeout(() => (showMessage = false), 3000);
}

const settingsClasses = getComponentClasses('CopyButton');
$: restProps = { ...defaults, ...$$restProps };
</script>

<Button
icon={mdiContentCopy}
{...$$restProps}
{...restProps}
class={cls('CopyButton', settingsClasses.root, $$props.class)}
on:click={() => {
navigator.clipboard.writeText(value);
Expand Down
9 changes: 5 additions & 4 deletions packages/svelte-ux/src/lib/components/DateButton.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,22 @@
import { DateToken, getDateFuncsByPeriodType, PeriodType } from '../utils/date';
import type { SelectedDate } from '../utils/date';
import { cls } from '../utils/styles';
import { getSettings } from './settings';
import { getComponentClasses } from './theme';
import { getComponentSettings, getSettings } from './settings';

const dispatch = createEventDispatcher();

const { classes: settingsClasses, defaults } = getComponentSettings('DateButton');

export let date: Date;
export let periodType: PeriodType;
export let disabled: boolean = false;
export let selected: SelectedDate;
export let hidden: boolean = false;
export let fade: boolean = false;
export let format = getCustomFormat(periodType);
export let variant = defaults.variant;

const { format: format_ux, localeSettings } = getSettings();
const settingsClasses = getComponentClasses('DateButton');

function getCustomFormat(periodType: PeriodType) {
switch (periodType) {
Expand Down Expand Up @@ -94,7 +95,7 @@
(disabled || fade) && 'opacity-25',
isCurrent ? 'font-bold' : 'font-normal'
)}
variant={isSelected ? 'fill' : 'default'}
variant={isSelected ? 'fill' : variant ?? 'default'}
color={isSelected || isCurrent ? 'primary' : 'default'}
{disabled}
on:click={() => {
Expand Down
8 changes: 4 additions & 4 deletions packages/svelte-ux/src/lib/components/DateField.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
import { createEventDispatcher } from 'svelte';
import { parse as parseDate } from 'date-fns';
import { PeriodType } from '../utils';
import { getSettings } from './settings';
import { getComponentSettings, getSettings } from './settings';

import Field from './Field.svelte';

import Input from './Input.svelte';
import DatePickerField from './DatePickerField.svelte';
import { getComponentClasses } from './theme';

const { format: format_ux } = getSettings();
const { classes: settingsClasses, defaults } = getComponentSettings('DateField');

export let value: Date | null = null;
export let format: string | undefined = undefined;
Expand All @@ -23,6 +23,7 @@

// Field props
export let label = '';
export let labelPlacement = defaults.labelPlacement;
export let error = '';
export let hint = '';
export let disabled = false;
Expand All @@ -32,8 +33,6 @@
export let dense = false;
export let icon: string | null = null;

const settingsClasses = getComponentClasses('DateField');

let inputValue: string | undefined = '';

const dispatch = createEventDispatcher();
Expand All @@ -60,6 +59,7 @@
{rounded}
{dense}
{clearable}
{labelPlacement}
on:clear={() => {
value = null;
inputValue = undefined;
Expand Down
7 changes: 4 additions & 3 deletions packages/svelte-ux/src/lib/components/DatePickerField.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
import Dialog from './Dialog.svelte';
import { DateToken, getDateFuncsByPeriodType, PeriodType } from '../utils/date';
import DateSelect from './DateSelect.svelte';
import { getComponentClasses } from './theme';
import { getSettings } from './settings';
import { getComponentSettings, getSettings } from './settings';

const dispatch = createEventDispatcher();
const { classes: settingsClasses, defaults } = getComponentSettings('DatePickerField');

export let value: Date | null = null;
export let periodType: PeriodType = PeriodType.Day;
Expand All @@ -20,6 +20,7 @@

// Field props
export let label: string | null = null;
export let labelPlacement = defaults.labelPlacement;
// export let value = '';
export let error = '';
export let hint = '';
Expand All @@ -31,7 +32,6 @@
export let icon: string | null = null;
export let center = false;

const settingsClasses = getComponentClasses('DatePickerField');
const { format, localeSettings } = getSettings();
$: dictionary = $format.settings.dictionary;

Expand Down Expand Up @@ -66,6 +66,7 @@
{:else}
<Field
label={label ?? $format(value, PeriodType.Day, { custom: secondaryFormat })}
{labelPlacement}
{icon}
{error}
{hint}
Expand Down
7 changes: 5 additions & 2 deletions packages/svelte-ux/src/lib/components/DateRangeField.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@
import { PeriodType, getDateFuncsByPeriodType } from '../utils/date';
import { getDateRangePresets, type DateRange as DateRangeType } from '../utils/dateRange';
import { cls } from '../utils/styles';
import { getSettings } from './settings';
import { getComponentSettings, getSettings } from './settings';

const dispatch = createEventDispatcher();
const { format, localeSettings } = getSettings();
const { classes: settingsClasses, defaults } = getComponentSettings('DateRangeField');

const _defaultValue: DateRangeType = {
from: null,
Expand Down Expand Up @@ -57,6 +58,8 @@
let open: boolean = false;

let currentValue = value;

$: restProps = { ...defaults, ...$$restProps };
</script>

<Field
Expand All @@ -71,7 +74,7 @@
{center}
classes={classes.field}
let:id
{...$$restProps}
{...restProps}
>
<span slot="prepend" class="flex items-center">
<slot name="prepend" />
Expand Down
10 changes: 6 additions & 4 deletions packages/svelte-ux/src/lib/components/Field.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
import { uniqueId } from 'lodash-es';

import { cls } from '../utils/styles';
import { getComponentClasses } from './theme';
import { type LabelPlacement, DEFAULT_LABEL_PLACEMENT } from '../types';
import { getComponentSettings } from './settings';

import Button from './Button.svelte';
import Icon from './Icon.svelte';
Expand All @@ -13,8 +14,10 @@
clear: null;
}>();

const { classes: settingsClasses, defaults } = getComponentSettings('Field');

export let label = '';
export let labelPlacement: 'inset' | 'float' | 'top' | 'left' = 'inset';
export let labelPlacement: LabelPlacement = defaults.labelPlacement ?? DEFAULT_LABEL_PLACEMENT;
export let value: any = null;
// export let placeholder = '';
export let error: string | string[] | boolean | undefined = '';
Expand All @@ -41,7 +44,6 @@
prepend?: string;
append?: string;
} = {};
const settingsClasses = getComponentClasses('Field');

$: hasValue = Array.isArray(value)
? value.length > 0
Expand Down Expand Up @@ -170,7 +172,7 @@
on:click={() => {
value = Array.isArray(value) ? [] : typeof value === 'string' ? '' : null;
dispatch('clear');
labelEl.focus();
labelEl?.focus();
}}
/>
{/if}
Expand Down
8 changes: 5 additions & 3 deletions packages/svelte-ux/src/lib/components/MenuButton.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte';
import type { ComponentProps } from '$lib/types';
import { getComponentSettings } from './settings';
import { mdiMenuDown } from '@mdi/js';

import { cls } from '../utils/styles';
Expand All @@ -9,9 +10,9 @@
import Icon from './Icon.svelte';
import Menu from './Menu.svelte';
import MenuItem from './MenuItem.svelte';
import { getComponentClasses } from './theme';

const dispatch = createEventDispatcher<{ change: { value: any } }>();
const { classes: settingsClasses, defaults } = getComponentSettings('MenuButton');

export let options: Array<{ label: string; value: any; icon?: string }>;
export let value: any = null;
Expand All @@ -24,14 +25,15 @@
label?: string;
icon?: string;
} = {};
const settingsClasses = getComponentClasses('MenuButton');

let open = false;

$: restProps = { ...defaults, ...$$restProps };
</script>

<Button
on:click={() => (open = !open)}
{...$$restProps}
{...restProps}
class={cls('MenuButton', settingsClasses.root, classes.root, $$props.class)}
>
<slot name="selection">
Expand Down
Loading