Skip to content

Commit

Permalink
feat(blur): adds blur as props
Browse files Browse the repository at this point in the history
  • Loading branch information
dvcol committed Feb 11, 2025
1 parent e4ec590 commit cceacc4
Show file tree
Hide file tree
Showing 27 changed files with 240 additions and 110 deletions.
42 changes: 20 additions & 22 deletions demo/components/DemoButtons.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -83,28 +83,26 @@
{/snippet}

<div class="row">
<div class="column">
<NeoButtonGroup>
<NeoButton toggle bind:checked={options.glass}>Glass</NeoButton>
<NeoButton toggle bind:checked={options.tinted}>Tinted</NeoButton>
<NeoButton toggle bind:checked={options.disabled}>Disabled</NeoButton>
<NeoButton toggle bind:checked={options.loading}>Loading</NeoButton>
<NeoButton toggle bind:checked={options.skeleton}>Skeleton</NeoButton>
</NeoButtonGroup>

<NeoSelect
label="Color"
placeholder="Select color"
position="left"
floating={false}
color={options.color}
display={displayValue}
size="10"
bind:value={options.color}
containerProps={{ style: 'margin-left: 6rem' }}
options={colorOptions}
/>
</div>
<NeoButtonGroup>
<NeoButton toggle bind:checked={options.glass}>Glass</NeoButton>
<NeoButton toggle bind:checked={options.tinted}>Tinted</NeoButton>
<NeoButton toggle bind:checked={options.disabled}>Disabled</NeoButton>
<NeoButton toggle bind:checked={options.loading}>Loading</NeoButton>
<NeoButton toggle bind:checked={options.skeleton}>Skeleton</NeoButton>
</NeoButtonGroup>

<NeoSelect
label="Color"
placeholder="Select color"
position="left"
floating={false}
color={options.color}
display={displayValue}
size="10"
bind:value={options.color}
containerProps={{ style: 'margin-left: 6rem' }}
options={colorOptions}
/>
</div>

<div class="row">
Expand Down
2 changes: 1 addition & 1 deletion demo/components/DemoTooltips.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@
position="left"
center
bind:value={options.elevation}
min={1}
min={0}
max={MaxShadowElevation}
defaultValue={DefaultShadowShallowElevation}
rounded={options.rounded}
Expand Down
6 changes: 5 additions & 1 deletion src/lib/buttons/NeoButton.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
DefaultShadowElevation,
DefaultShadowHoverElevation,
isShadowFlat,
type ShadowElevation,
} from '~/utils/shadow.utils.js';
import { quickDurationProps } from '~/utils/transition.utils.js';
Expand Down Expand Up @@ -83,6 +84,7 @@
hover: _hover = DefaultShadowHoverElevation,
active: _active = DefaultShadowActiveElevation,
pressed: _pressed,
blur: _blur,
...rest
} = $derived.by(() => {
if (text || ghost) return { ...NeoTextButton, ..._rest };
Expand All @@ -94,7 +96,9 @@
const active = $derived(coerce(_active));
const activePressed = $derived(_pressed ?? elevation + hover > 0);
const filter = $derived(computeGlassFilter(elevation, glass));
const blur = $derived(coerce<ShadowElevation>(_blur ?? elevation));
const filter = $derived(computeGlassFilter(blur, glass));
const boxShadow = $derived(computeShadowElevation(elevation, { glass }));
const hoverShadow = $derived(computeHoverShadowElevation(elevation, hover, { glass }) ?? boxShadow);
const activeShadow = $derived(
Expand Down
34 changes: 30 additions & 4 deletions src/lib/buttons/NeoButtonGroup.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,17 @@
import { toAction, toActionProps, toTransition, toTransitionProps } from '~/utils/action.utils.js';
import { getColorVariable } from '~/utils/colors.utils.js';
import { coerce, computeGlassFilter, computeShadowElevation, getDefaultElevation } from '~/utils/shadow.utils.js';
import {
coerce,
computeGlassFilter,
computeHoverShadowElevation,
computeShadowElevation,
DefaultShadowActiveElevation,
DefaultShadowElevation,
DefaultShadowHoverElevation,
getDefaultElevation,
type ShadowElevation,
} from '~/utils/shadow.utils.js';
/* eslint-disable prefer-const -- necessary for binding checked */
let {
Expand Down Expand Up @@ -44,14 +54,28 @@
use,
// Other props
...rest
..._rest
}: NeoButtonGroupProps = $props();
/* eslint-enable prefer-const */
const elevation = $derived(coerce(rest?.elevation ?? getDefaultElevation(pressed)));
const {
elevation: _elevation = DefaultShadowElevation,
buttonHover: _hover = DefaultShadowHoverElevation,
buttonActive: _active = DefaultShadowActiveElevation,
blur: _blur,
...rest
} = $derived(_rest);
const elevation = $derived(coerce(_elevation ?? getDefaultElevation(pressed)));
const hover = $derived(coerce(_hover));
const active = $derived(coerce(_active));
const blur = $derived(coerce<ShadowElevation>(_blur ?? elevation));
const filter = $derived(computeGlassFilter(blur, glass));
const filter = $derived(computeGlassFilter(elevation, glass));
const boxShadow = $derived(computeShadowElevation(elevation, { glass, pressed, convex }));
const hoverShadow = $derived(computeHoverShadowElevation(elevation, hover, { glass }) ?? boxShadow);
const activeShadow = $derived(computeShadowElevation(active, { glass, pressed: false, active: glass }) ?? boxShadow);
const inFn = $derived(toTransition(inAction ?? transitionAction));
const inProps = $derived(toTransitionProps(inAction ?? transitionAction));
Expand Down Expand Up @@ -102,6 +126,8 @@
class:neo-nowrap={nowrap}
style:--neo-btn-group-text-color={getColorVariable(color)}
style:--neo-btn-group-box-shadow={boxShadow}
style:--neo-btn-group-box-shadow-hover={hoverShadow}
style:--neo-btn-group-box-shadow-active={activeShadow}
style:--neo-btn-group-glass-blur={filter}
style:justify-content={justify}
style:align-items={align}
Expand Down
5 changes: 3 additions & 2 deletions src/lib/buttons/NeoCheckboxButton.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,13 @@
skeleton = false,
// Other props
...rest
..._rest
}: NeoCheckboxButtonProps = $props();
/* eslint-enable prefer-const */
const elevation = $derived(coerce(rest?.elevation ?? DefaultShadowShallowElevation));
const { elevation: _elevation = DefaultShadowShallowElevation, ...rest } = $derived(_rest);
const elevation = $derived(coerce(_elevation));
const boxShadow = $derived(computeShadowElevation(elevation, { glass, active: glass }, DefaultShallowMinMaxElevation));
const checkedShadow = $derived(
computeShadowElevation(-Math.abs(elevation), { glass, active: glass, pressed: elevation > 0 }, DefaultShallowMinMaxElevation),
Expand Down
5 changes: 3 additions & 2 deletions src/lib/buttons/NeoRadioButton.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@
skeleton = false,
// Other props
...rest
..._rest
}: NeoRadioButtonProps = $props();
/* eslint-enable prefer-const */
const elevation = $derived(coerce(rest?.elevation ?? DefaultShadowShallowElevation));
const { elevation: _elevation = DefaultShadowShallowElevation, ...rest } = $derived(_rest);
const elevation = $derived(coerce(_elevation));
const boxShadow = $derived(computeShadowElevation(elevation, { glass, active: glass }, DefaultShallowMinMaxElevation));
const checkedShadow = $derived(
computeShadowElevation(-Math.abs(elevation), { glass, active: glass, pressed: elevation > 0 }, DefaultShallowMinMaxElevation),
Expand Down
6 changes: 4 additions & 2 deletions src/lib/buttons/NeoSwitchButton.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@
skeleton = false,
// Other props
...rest
..._rest
}: NeoSwitchButtonProps = $props();
/* eslint-enable prefer-const */
const elevation = $derived(coerce(rest?.elevation ?? DefaultShadowShallowElevation));
const { elevation: _elevation = DefaultShadowShallowElevation, ...rest } = $derived(_rest);
const elevation = $derived(coerce(_elevation));
const boxShadow = $derived(computeShadowElevation(-Math.abs(elevation), { glass, pressed: elevation > 0 }, DefaultShallowMinMaxElevation));
const context = $derived<NeoSwitchButtonContext>({ checked, indeterminate, disabled });
Expand Down
20 changes: 20 additions & 0 deletions src/lib/buttons/neo-button-group.model.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { NeoButtonActiveElevation, NeoButtonBlur, NeoButtonHoverElevation } from 'src/lib/index.js';
import type { Snippet } from 'svelte';
import type { HTMLActionProps } from '~/utils/action.utils.js';
import type { Color } from '~/utils/colors.utils.js';
Expand All @@ -20,6 +21,25 @@ export type NeoButtonGroupContext = {
* @default 3
*/
elevation?: NeoButtonGroupElevation;
/**
* The blur level to apply.
*
* @default elevation, min: 1, max: 5
* @see glass
*/
blur?: NeoButtonBlur;
/**
* Button hover elevation.
*
* @default -1 (relative to base elevation)
*/
buttonHover?: NeoButtonHoverElevation;
/**
* Button active elevation.
*
* @default -2 (relative to base elevation)
*/
buttonActive?: NeoButtonActiveElevation;
/**
* If true, negative elevation (< 0) will be displayed as pressed instead of inset.
*/
Expand Down
20 changes: 15 additions & 5 deletions src/lib/buttons/neo-button.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ import type { HTMLActionProps } from '~/utils/action.utils.js';
import type { Color } from '~/utils/colors.utils.js';
import type { HTMLFlexProps, HTMLNeoBaseElement, HTMLRefProps, SvelteEvent } from '~/utils/html-element.utils.js';

import {
type ShadowElevation,
type ShadowElevationString,
type ShadowHoverElevation,
type ShadowHoverElevationsString,
import type {
BlurElevation,
BlurElevationString,
ShadowElevation,
ShadowElevationString,
ShadowHoverElevation,
ShadowHoverElevationsString,
} from '~/utils/shadow.utils.js';

export type NeoButtonBlur = BlurElevation | BlurElevationString;
export type NeoButtonElevation = ShadowElevation | ShadowElevationString;
export type NeoButtonHoverElevation = ShadowHoverElevation | ShadowHoverElevationsString;
export type NeoButtonActiveElevation = ShadowHoverElevation | ShadowHoverElevationsString;
Expand Down Expand Up @@ -114,6 +117,13 @@ export type NeoButtonProps<Tag extends keyof HTMLElementTagNameMap = 'button'> =
* @default -2 (relative to base elevation)
*/
active?: NeoButtonActiveElevation;
/**
* The blur level to apply to the button when in glass mode.
*
* @default elevation, min: 1, max: 5
* @see glass
*/
blur?: NeoButtonBlur;
/**
* Weather the pressed state should be displayed as recessed or pressed.
*
Expand Down
12 changes: 8 additions & 4 deletions src/lib/cards/NeoCard.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
computeShadowElevation,
getDefaultElevation,
isShadowFlat,
type ShadowElevation,
} from '~/utils/shadow.utils.js';
import { toSize } from '~/utils/style.utils.js';
Expand Down Expand Up @@ -82,7 +83,7 @@
mediaProps,
dividerProps,
closeProps,
...rest
..._rest
}: NeoCardProps = $props();
/* eslint-enable prefer-const */
Expand All @@ -92,10 +93,13 @@
const { tag: actionTag = 'div', ...actionRest } = $derived(actionProps ?? {});
const { tag: mediaTag = 'div', ...mediaRest } = $derived(mediaProps ?? {});
const elevation = $derived(coerce(rest?.elevation ?? getDefaultElevation(pressed)));
const hover = $derived(coerce(rest?.hover ?? 0));
const { elevation: _elevation, hover: _hover = 0, blur: _blur, ...rest } = $derived(_rest);
const filter = $derived(computeGlassFilter(elevation, glass));
const elevation = $derived(coerce(_elevation ?? getDefaultElevation(pressed)));
const hover = $derived(coerce(_hover));
const blur = $derived(coerce<ShadowElevation>(_blur ?? elevation));
const filter = $derived(computeGlassFilter(blur, glass));
const boxShadow = $derived(computeShadowElevation(elevation, { glass, pressed, convex }));
const hoverElevation = $derived(elevation + hover);
Expand Down
17 changes: 16 additions & 1 deletion src/lib/cards/neo-card.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,17 @@ import type { NeoButtonProps } from '~/buttons/neo-button.model.js';
import type { HTMLActionProps } from '~/utils/action.utils.js';
import type { Color } from '~/utils/colors.utils.js';
import type { HTMLFlexProps, HTMLNeoBaseElement, HTMLRefProps, HTMLTagProps } from '~/utils/html-element.utils.js';
import type { ShadowElevation, ShadowElevationString, ShadowHoverElevation, ShadowHoverElevationsString } from '~/utils/shadow.utils.js';
import type {
BlurElevation,
BlurElevationString,
ShadowElevation,
ShadowElevationString,
ShadowHoverElevation,
ShadowHoverElevationsString,
} from '~/utils/shadow.utils.js';
import type { SizeInput } from '~/utils/style.utils.js';

export type NeoCardBlur = BlurElevation | BlurElevationString;
export type NeoCardElevation = ShadowElevation | ShadowElevationString;
export type NeoCardHoverElevation = ShadowHoverElevation | ShadowHoverElevationsString;

Expand All @@ -29,6 +37,13 @@ export type NeoCardContext = {
* @default 0
*/
hover?: NeoCardHoverElevation;
/**
* The blur level to apply when in glass mode.
*
* @default elevation, min: 1, max: 5
* @see glass
*/
blur?: NeoCardBlur;
/**
* If the card is currently hovered.
*/
Expand Down
6 changes: 4 additions & 2 deletions src/lib/divider/NeoDivider.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@
rounded = true,
// Other props
...rest
..._rest
}: NeoDividerProps = $props();
const elevation = $derived(coerce(rest?.elevation ?? 0));
const { elevation: _elevation = 0, ...rest } = $derived(_rest);
const elevation = $derived(coerce(_elevation));
const boxShadow = $derived(computeShadowElevation(elevation));
const minimum = $derived.by(() => {
Expand Down
5 changes: 3 additions & 2 deletions src/lib/inputs/NeoCheckbox.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,15 @@
containerProps,
wrapperRef = $bindable(),
wrapperProps,
...rest
..._rest
}: NeoCheckboxProps = $props();
/* eslint-enable prefer-const */
const { tag: containerTag = 'div', ...containerRest } = $derived(containerProps ?? {});
const { elevation: _elevation = DefaultShadowShallowElevation, ...rest } = $derived(_rest);
const elevation = $derived(coerce(_elevation));
const labelId = $derived(label ? `neo-checkbox-label-${getUUID()}` : undefined);
const elevation = $derived(coerce(rest?.elevation ?? DefaultShadowShallowElevation));
let initial = $state(checked);
let validationMessage = $state<string>(ref?.validationMessage ?? '');
Expand Down
2 changes: 0 additions & 2 deletions src/lib/inputs/NeoColorPicker.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,6 @@
onclick,
});
$inspect(afterProps);
const oninput: FormEventHandler<HTMLInputElement> = e => {
ref?.dispatchEvent(new InputEvent(e.type, e));
pickerProps?.oninput?.(e);
Expand Down
5 changes: 3 additions & 2 deletions src/lib/inputs/NeoRadio.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,15 @@
labelProps,
buttonProps,
containerProps,
...rest
..._rest
}: NeoRadioProps = $props();
/* eslint-enable prefer-const */
const { tag: containerTag = 'div', ...containerRest } = $derived(containerProps ?? {});
const { elevation: _elevation = DefaultShadowShallowElevation, ...rest } = $derived(_rest);
const elevation = $derived(coerce(_elevation));
const labelId = $derived(label ? `neo-radio-label-${getUUID()}` : undefined);
const elevation = $derived(coerce(rest?.elevation ?? DefaultShadowShallowElevation));
let initial = $state(checked);
let validationMessage = $state<string>(ref?.validationMessage ?? '');
Expand Down
Loading

0 comments on commit cceacc4

Please sign in to comment.