Skip to content

Commit

Permalink
Allow per-component defaults as well
Browse files Browse the repository at this point in the history
  • Loading branch information
dimfeld committed Feb 6, 2024
1 parent 9d5118f commit 71abd92
Show file tree
Hide file tree
Showing 18 changed files with 196 additions and 81 deletions.
19 changes: 7 additions & 12 deletions packages/svelte-ux/src/lib/components/Button.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@
import { multi } from '../actions/multi';
import type { Actions } from '../actions/multi';
import type { ThemeColors } from '$lib/types';
import { getComponentClasses } from './theme';
import { getButtonGroup } from './ButtonGroup.svelte';
import { asIconData, type IconInput } from '$lib/utils/icons';
import type { ButtonVariant } from '$lib/types/options';
import { getComponentSettings } from './settings';
const { defaults } = getComponentSettings('Button');
const settingsClasses = defaults.classes;
export let type: 'button' | 'submit' | 'reset' = 'button';
export let href: string | undefined = undefined;
Expand All @@ -22,15 +26,7 @@
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 variant: ButtonVariant | 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
Expand All @@ -40,11 +36,10 @@
icon?: string;
loading?: string;
} = {};
const settingsClasses = getComponentClasses('Button');
// Override default from `ButtonGroup` if set
const groupContext = getButtonGroup();
$: variant = variant ?? groupContext?.variant ?? 'default';
$: variant = variant ?? groupContext?.variant ?? defaults.variant ?? 'default';
$: size = size ?? groupContext?.size ?? 'md';
$: color = color ?? groupContext?.color ?? 'default';
$: rounded = rounded ?? groupContext?.rounded ?? (iconOnly ? 'full' : true);
Expand Down
20 changes: 7 additions & 13 deletions packages/svelte-ux/src/lib/components/ButtonGroup.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,12 @@
import { type ComponentProps, setContext, getContext } from 'svelte';
import type Button from './Button.svelte';
import type { ThemeColors } from '$lib/types';
import type { ButtonVariant } from '$lib/types/options';
// 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'];
variant: ButtonVariant | undefined;
size: 'sm' | 'md' | 'lg' | undefined; //ButtonProps['size'];
color: ThemeColors | 'default' | undefined; //ButtonProps['color'];
rounded: boolean | 'full' | undefined; // ButtonProps['rounded']
Expand All @@ -33,16 +26,17 @@

<script lang="ts">
import { cls } from '../utils/styles';
import { getComponentClasses } from './theme';
import { getComponentSettings } from './settings';
export let variant: ComponentProps<Button>['variant'] = undefined;
const { defaults } = getComponentSettings('ButtonGroup');
const settingsClasses = defaults.classes;
export let variant: ComponentProps<Button>['variant'] = defaults.variant;
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 settingsClasses = getComponentClasses('ButtonGroup');
$: _class = cls(
'ButtonGroup',
'inline-flex',
Expand Down
9 changes: 6 additions & 3 deletions packages/svelte-ux/src/lib/components/CopyButton.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +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 { defaults } = getComponentSettings('CopyButton');
const settingsClasses = defaults.classes;
export let value: string;
export let variant = defaults.variant;
let showMessage = false;
$: if (showMessage) {
setTimeout(() => (showMessage = false), 3000);
}
const settingsClasses = getComponentClasses('CopyButton');
</script>

<Button
icon={mdiContentCopy}
{variant}
{...$$restProps}
class={cls('CopyButton', settingsClasses.root, $$props.class)}
on:click={() => {
Expand Down
10 changes: 6 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,23 @@
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 { defaults } = getComponentSettings('DateButton');
const settingsClasses = defaults.classes;
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 +96,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,21 +2,22 @@
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 { defaults } = getComponentSettings('DateField');
export let value: Date | null = null;
export let format: string | undefined = undefined;
export let mask: string | undefined = undefined;
export let replace = 'dmyh';
export let picker = false;
export let labelPlacement = defaults.labelPlacement;
$: actualFormat = format ?? $format_ux.settings.formats.dates.baseParsing ?? 'MM/dd/yyyy';
$: actualMask = mask ?? actualFormat.toLowerCase();
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,15 +8,16 @@
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 { defaults } = getComponentSettings('DatePickerField');
export let value: Date | null = null;
export let periodType: PeriodType = PeriodType.Day;
export let iconOnly: boolean = false;
export let stepper: boolean = false;
export let labelPlacement = defaults.labelPlacement;
// Field props
export let label: string | null = null;
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
5 changes: 4 additions & 1 deletion 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 { defaults } = getComponentSettings('DatePickerField');
const _defaultValue: DateRangeType = {
from: null,
Expand Down Expand Up @@ -53,6 +54,7 @@
export let rounded = false;
export let dense = false;
export let icon: string | null = null;
export let labelPlacement = defaults.labelPlacement;
let open: boolean = false;
Expand All @@ -61,6 +63,7 @@

<Field
label={label ?? (value.periodType ? $format.getPeriodTypeName(value.periodType) : '')}
{labelPlacement}
{icon}
{error}
{hint}
Expand Down
8 changes: 5 additions & 3 deletions packages/svelte-ux/src/lib/components/Field.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@
clear: null;
}>();
const { classes: settingsClasses, defaultProps } = getComponentSettings('Field');
const { defaults, globalDefaults } = getComponentSettings('Field');
const settingsClasses = defaults.classes;
export let label = '';
export let labelPlacement: LabelPlacement = defaultProps.labelPlacement;
export let labelPlacement: LabelPlacement =
defaults.labelPlacement ?? globalDefaults.labelPlacement;
export let value: any = null;
// export let placeholder = '';
export let error: string | string[] | boolean | undefined = '';
Expand Down Expand Up @@ -172,7 +174,7 @@
on:click={() => {
value = Array.isArray(value) ? [] : typeof value === 'string' ? '' : null;
dispatch('clear');
labelEl.focus();
labelEl?.focus();
}}
/>
{/if}
Expand Down
6 changes: 4 additions & 2 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,22 +10,23 @@
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 { defaults } = getComponentSettings('MenuButton');
const settingsClasses = defaults.classes;
export let options: Array<{ label: string; value: any; icon?: string }>;
export let value: any = null;
export let menuProps: ComponentProps<Menu> = { placement: 'bottom-start' };
export let menuIcon: string | null = mdiMenuDown;
export let variant = defaults.variant;
$: selected = options?.find((x) => x.value === value);
export let classes: {
root?: string;
label?: string;
icon?: string;
} = {};
const settingsClasses = getComponentClasses('MenuButton');
let open = false;
</script>
Expand Down
8 changes: 6 additions & 2 deletions packages/svelte-ux/src/lib/components/MenuField.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@
import Menu from './Menu.svelte';
import MenuItem from './MenuItem.svelte';
import Button from './Button.svelte';
import { getComponentClasses } from './theme';
import type { MenuOption } from '$lib/types/options';
import { getComponentSettings } from './settings';
const { defaults } = getComponentSettings('MenuField');
const settingsClasses = defaults.classes;
export let options: MenuOption[] = [];
export let value: any = null;
Expand All @@ -20,6 +23,7 @@
resize: true,
};
export let menuIcon = mdiMenuDown;
export let labelPlacement = defaults.labelPlacement;
/** If true, show left/right buttons to step through options */
export let stepper = false;
Expand All @@ -29,7 +33,6 @@
menuIcon?: string;
group?: string;
} = {};
const settingsClasses = getComponentClasses('MenuField');
let open = false;
export let selected: any = undefined;
Expand Down Expand Up @@ -68,6 +71,7 @@
<Field
class="cursor-pointer"
{...$$restProps}
{labelPlacement}
classes={{ input: 'overflow-hidden', ...$$props.classes }}
on:click={() => (open = !open)}
>
Expand Down
8 changes: 6 additions & 2 deletions packages/svelte-ux/src/lib/components/MultiSelectField.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import { getComponentClasses } from './theme';
import { getComponentSettings } from './settings';
import { createEventDispatcher, type ComponentProps, type ComponentEvents } from 'svelte';
import { get } from 'lodash-es';
Expand All @@ -18,6 +18,9 @@
type Option = $$Generic;
const { defaults } = getComponentSettings('MultiSelectField');
const settingsClasses = defaults.classes;
// MultiSelectMenu props
export let options: Option[];
export let value: any[] = [];
Expand All @@ -32,6 +35,7 @@
export let placeholder = '';
export let loading: boolean = false;
export let disabled: boolean = false;
export let labelPlacement = defaults.labelPlacement;
// export let readonly: boolean = false;
export let icon: string | null = null;
export let clearable = true;
Expand All @@ -48,7 +52,6 @@
field?: string;
actions?: string;
} = {};
const settingsClasses = getComponentClasses('MultiSelectField');
const dispatch = createEventDispatcher<{ change: { value: typeof value } }>();
Expand Down Expand Up @@ -140,6 +143,7 @@
<!-- on:blur={onBlur} -->
<TextField
{label}
{labelPlacement}
{placeholder}
{base}
{rounded}
Expand Down
Loading

0 comments on commit 71abd92

Please sign in to comment.