Skip to content

Commit

Permalink
Merge branch 'develop' of https://github.com/melt-ui/melt-ui into dev…
Browse files Browse the repository at this point in the history
…elop
  • Loading branch information
TGlide committed Jun 27, 2024
2 parents cf20fc7 f8e5f06 commit f75fe43
Show file tree
Hide file tree
Showing 18 changed files with 218 additions and 45 deletions.
5 changes: 5 additions & 0 deletions .changeset/clean-tomatoes-lie.md
Original file line number Diff line number Diff line change
@@ -0,0 1,5 @@
---
"@melt-ui/svelte": minor
---

Added prop to createToaster() to pause all timers on hover
5 changes: 5 additions & 0 deletions .changeset/fifty-suits-reflect.md
Original file line number Diff line number Diff line change
@@ -0,0 1,5 @@
---
'@melt-ui/svelte': patch
---

fix(slider): `onValueCommitted` called if the slider had an active state
5 changes: 5 additions & 0 deletions .changeset/khaki-maps-relate.md
Original file line number Diff line number Diff line change
@@ -0,0 1,5 @@
---
"@melt-ui/svelte": minor
---

feat(tags-input): split on paste
5 changes: 5 additions & 0 deletions .changeset/tasty-tools-accept.md
Original file line number Diff line number Diff line change
@@ -0,0 1,5 @@
---
'@melt-ui/svelte': minor
---

add `name` prop to radio group builder hidden input element
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 8,7 @@
"dev": "vite dev",
"build": "vite build && npm run package",
"deploy": "vite build",
"prepare": "svelte-kit sync",
"preview": "vite preview",
"package": "svelte-kit sync && svelte-package && publint",
"prepublishOnly": "npm run package",
Expand Down
5 changes: 5 additions & 0 deletions src/docs/data/builders/combobox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 31,11 @@ const OPTION_PROPS = [
description:
'When true, hovering an option will update the `highlightedItem` store, and when the cursor leaves an option the store will be set to `null`',
},
{
name: 'name',
type: 'string',
description: 'The name to be used for the hidden input.',
},
];

const BUILDER_NAME = 'combobox';
Expand Down
5 changes: 5 additions & 0 deletions src/docs/data/builders/radio-group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 17,11 @@ const OPTION_PROPS = [
default: '"vertical"',
description: 'The orientation of the radio group.',
},
{
name: 'name',
type: 'string',
description: 'The name to be used for the hidden input.',
},
];
const BUILDER_NAME = 'radio group';

Expand Down
8 changes: 7 additions & 1 deletion src/docs/data/builders/toast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 20,12 @@ const OPTION_PROPS = [
default: "'foreground'",
description: 'The sensitivity of the toast for accessibility purposes.',
},
{
name: 'hover',
type: ["'pause'", "'pause-all'", 'null'],
default: "'pause'",
description: 'The behavior when a toast is hovered.',
},
];

const BUILDER_NAME = 'toast';
Expand Down Expand Up @@ -129,7 135,7 @@ const keyboard: KeyboardSchema = [
];

const schemas = [builder, content, title, description, close];
const features = ['Automatically closes', 'Resets closing on hover'];
const features = ['Automatically closes', 'Pause closing on hover (single, all, none)'];

export const toastData: BuilderData = {
schemas,
Expand Down
12 changes: 9 additions & 3 deletions src/docs/previews/toast/progress/tailwind/index.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 7,20 @@
</script>

<script lang="ts">
import { createToaster } from '$lib/index.js';
import { writable, type Writable } from 'svelte/store';
import { createToaster, type CreateToasterProps } from '$lib/index.js';
import { flip } from 'svelte/animate';
import Toast from './toast.svelte';
import SelectHover from './select-hover.svelte';
const {
const hover: Writable<CreateToasterProps['hover']> = writable('pause');
$: ({
elements,
helpers: { addToast },
states: { toasts },
actions: { portal },
} = createToaster<ToastData>();
} = createToaster<ToastData>({ hover: $hover }));
const toastData: ToastData[] = [
{
Expand All @@ -41,6 45,8 @@
}
</script>

<SelectHover bind:value={$hover} />

<button
class="inline-flex items-center justify-center rounded-xl bg-white px-4 py-3
font-medium leading-none text-magnum-700 shadow hover:opacity-75"
Expand Down
82 changes: 82 additions & 0 deletions src/docs/previews/toast/progress/tailwind/select-hover.svelte
Original file line number Diff line number Diff line change
@@ -0,0 1,82 @@
<script lang="ts">
import { Check, ChevronDown } from '$icons/index.js';
import { createSelect, melt, type CreateToasterProps } from '$lib/index.js';
import { fade } from 'svelte/transition';
const options: { value: CreateToasterProps['hover']; label: string }[] = [
{ value: 'pause', label: 'pause' },
{ value: 'pause-all', label: 'pause-all' },
{ value: null, label: 'null' },
];
const {
elements: { trigger, menu, option, label },
states: { selected, selectedLabel, open },
helpers: { isSelected },
} = createSelect<CreateToasterProps['hover']>({
forceVisible: true,
positioning: {
placement: 'bottom',
fitViewport: true,
sameWidth: true,
},
defaultSelected: { value: 'pause', label: 'pause' },
});
export let value: CreateToasterProps['hover'];
$: value = $selected?.value;
</script>

<div class="absolute left-4 top-4">
<div class="flex flex-col gap-1">
<!-- svelte-ignore a11y-label-has-associated-control - $label contains the 'for' attribute -->
<label class="block text-white" use:melt={$label}> Hover behavior : </label>
<button
class="flex h-10 min-w-[220px] items-center justify-between rounded-lg bg-white px-3 py-2
text-magnum-700 shadow transition-opacity hover:opacity-90"
use:melt={$trigger}
aria-label="Hover behavior"
>
{$selectedLabel || 'Select hover behavior'}
<ChevronDown class="size-5" />
</button>
{#if $open}
<div
class="force-dark z-10 flex max-h-[300px] flex-col
overflow-y-auto rounded-lg bg-white p-1
shadow focus:!ring-0"
use:melt={$menu}
transition:fade={{ duration: 150 }}
>
{#each options as { value, label }}
<div
class="relative cursor-pointer rounded-lg py-1 pl-8 pr-4 text-neutral-800
hover:bg-magnum-100 focus:z-10
focus:text-magnum-700
data-[highlighted]:bg-magnum-200 data-[highlighted]:text-magnum-900
data-[disabled]:opacity-50"
use:melt={$option({ value, label })}
>
<div class="check {$isSelected(value) ? 'block' : 'hidden'}">
<Check class="size-4" />
</div>

{label}
</div>
{/each}
</div>
{/if}
</div>
</div>

<style lang="postcss">
.check {
position: absolute;
left: theme(spacing.2);
top: 50%;
z-index: theme(zIndex.20);
translate: 0 calc(-50% 1px);
color: theme(colors.magnum.500);
}
</style>
6 changes: 4 additions & 2 deletions src/lib/builders/radio-group/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 16,7 @@ import {
} from '$lib/internal/helpers/index.js';
import { safeOnMount } from '$lib/internal/helpers/lifecycle.js';
import type { Defaults, MeltActionReturn } from '$lib/internal/types.js';
import { derived, writable } from 'svelte/store';
import { derived, readonly, writable } from 'svelte/store';
import { createHiddenInput } from '../hidden-input/create.js';
import type { RadioGroupEvents } from './events.js';
import type { CreateRadioGroupProps, RadioGroupItemProps } from './types.js';
Expand All @@ -27,6 27,7 @@ const defaults = {
disabled: false,
required: false,
defaultValue: undefined,
name: undefined,
} satisfies Defaults<CreateRadioGroupProps>;

type RadioGroupParts = 'item' | 'hidden-input';
Expand All @@ -38,7 39,7 @@ export function createRadioGroup(props?: CreateRadioGroupProps) {

// options
const options = toWritableStores(omit(withDefaults, 'value'));
const { disabled, required, loop, orientation } = options;
const { disabled, required, loop, orientation, name: nameProp } = options;

const valueWritable = withDefaults.value ?? writable(withDefaults.defaultValue);
const value = overridable(valueWritable, withDefaults?.onValueChange);
Expand Down Expand Up @@ -177,6 178,7 @@ export function createRadioGroup(props?: CreateRadioGroupProps) {

const hiddenInput = createHiddenInput({
value,
name: readonly(nameProp),
disabled,
required,
});
Expand Down
2 changes: 2 additions & 0 deletions src/lib/builders/radio-group/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 20,8 @@ export type CreateRadioGroupProps = {
*/
required?: boolean;

name?: string;

/**
* Whether or not the radio group should loop around when the end
* is reached.
Expand Down
6 changes: 3 additions & 3 deletions src/lib/builders/slider/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -521,11 521,11 @@ export const createSlider = (props?: CreateSliderProps) => {
};

const pointerUp = () => {
isActive.set(false);

if (withDefaults?.onValueCommitted) {
if (withDefaults?.onValueCommitted && isActive.get()) {
withDefaults.onValueCommitted(value.get());
}

isActive.set(false);
};

const unsub = executeCallbacks(
Expand Down
36 changes: 21 additions & 15 deletions src/lib/builders/tags-input/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -339,11 339,17 @@ export function createTagsInput(props?: CreateTagsInputProps) {
if (!addOnPaste.get()) return;
e.preventDefault();

// Update value with the pasted text or set invalid
if (isInputValid(pastedText) && (await addTag(pastedText))) {
node.value = '';
} else {
inputInvalid.set(true);
const newTags = pastedText.split(',')
addTag: for (let i = 0; i < newTags.length; i ) {
const newTag = newTags[i];
// Update value with the pasted tag or set invalid
if (isInputValid(newTag) && (await addTag(newTag))) {
continue addTag;
} else {
node.value = newTags.slice(i).join(',');
inputInvalid.set(true);
return;
}
}
}),
addMeltEventListener(node, 'keydown', async (e) => {
Expand Down Expand Up @@ -498,11 504,11 @@ export function createTagsInput(props?: CreateTagsInputProps) {
tabindex: -1,
style: editing
? styleToString({
position: 'absolute',
opacity: 0,
'pointer-events': 'none',
margin: 0,
})
position: 'absolute',
opacity: 0,
'pointer-events': 'none',
margin: 0,
})
: undefined,
} as const;
};
Expand Down Expand Up @@ -638,11 644,11 @@ export function createTagsInput(props?: CreateTagsInputProps) {
tabindex: -1,
style: !editing
? styleToString({
position: 'absolute',
opacity: 0,
'pointer-events': 'none',
margin: 0,
})
position: 'absolute',
opacity: 0,
'pointer-events': 'none',
margin: 0,
})
: undefined,
} as const;
};
Expand Down
Loading

0 comments on commit f75fe43

Please sign in to comment.