Skip to content

Commit

Permalink
APP-3126: make searchable select autoresize (viamrobotics#462)
Browse files Browse the repository at this point in the history
  • Loading branch information
mcous authored Jan 9, 2024
1 parent a6aff3c commit fa44161
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 39 deletions.
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@viamrobotics/prime-core",
"version": "0.0.78",
"version": "0.0.79",
"publishConfig": {
"access": "public"
},
Expand Down
9 changes: 9 additions & 0 deletions packages/core/src/lib/floating/floating-size.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { FloatingSizeOptions } from './floating-style';

export const matchWidth: FloatingSizeOptions = {
apply({ rects, elements }) {
Object.assign(elements.floating.style, {
width: `${rects.reference.width}px`,
});
},
};
37 changes: 17 additions & 20 deletions packages/core/src/lib/floating/floating-style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ import {
type Side,
type ComputePositionConfig,
type ReferenceElement,
type OffsetOptions,
type FlipOptions,
type ShiftOptions,
type SizeOptions,
} from '@floating-ui/dom';

import { derived, writable, type Readable } from 'svelte/store';
Expand All @@ -19,6 +23,10 @@ import { noop } from 'lodash-es';
export type {
Placement as FloatingPlacement,
ReferenceElement as FloatingReferenceElement,
OffsetOptions as FloatingOffsetOptions,
FlipOptions as FloatingFlipOptions,
ShiftOptions as FloatingShiftOptions,
SizeOptions as FloatingSizeOptions,
} from '@floating-ui/dom';

export interface FloatingStyleStore
Expand All @@ -43,11 +51,11 @@ export interface State {
referenceElement?: ReferenceElement | undefined;
floatingElement?: HTMLElement | undefined;
arrowElement?: Element | undefined;
placement?: Placement;
offset?: number;
flip?: boolean;
shift?: number;
matchWidth?: boolean;
placement?: Placement | undefined;
offset?: OffsetOptions | undefined;
flip?: FlipOptions | undefined;
shift?: ShiftOptions | undefined;
size?: SizeOptions | undefined;
auto?: boolean;
}

Expand Down Expand Up @@ -111,27 +119,16 @@ const calculateStyle = async (state: State): Promise<FloatingStyle> => {
};

const getConfig = (state: State): ComputePositionConfig => {
const { arrowElement, placement, offset, flip, shift, matchWidth } = state;
const { arrowElement, placement, offset, flip, shift, size } = state;

return {
placement: placement ?? 'top',
middleware: [
offset !== undefined && offsetMiddleware(offset),
flip &&
flipMiddleware({
fallbackAxisSideDirection: 'start',
crossAxis: shift === undefined,
}),
shift !== undefined && shiftMiddleware({ padding: shift }),
flip !== undefined && flipMiddleware(flip),
shift !== undefined && shiftMiddleware(shift),
arrowElement && arrowMiddleware({ element: arrowElement }),
matchWidth &&
sizeMiddleware({
apply({ rects, elements }) {
Object.assign(elements.floating.style, {
width: `${rects.reference.width}px`,
});
},
}),
size !== undefined && sizeMiddleware(size),
],
};
};
Expand Down
15 changes: 12 additions & 3 deletions packages/core/src/lib/floating/floating.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,18 @@ import {
floatingStyle,
type FloatingReferenceElement,
type FloatingPlacement,
type FloatingFlipOptions,
type FloatingShiftOptions,
type FloatingSizeOptions,
} from './floating-style';
export let referenceElement: FloatingReferenceElement | undefined;
export let placement: FloatingPlacement = 'bottom-start';
export let offset = 0;
export let matchWidth = false;
export let offset: number | undefined = undefined;
export let flip: FloatingFlipOptions | undefined = undefined;
export let shift: FloatingShiftOptions | undefined = undefined;
export let size: FloatingSizeOptions | undefined = undefined;
export let auto = false;
export let onClickOutside: ((target: Element) => unknown) | undefined =
undefined;
Expand All @@ -25,7 +31,10 @@ $: style.register({
floatingElement,
placement,
offset,
matchWidth,
flip,
shift,
size,
auto,
});
</script>

Expand Down
1 change: 1 addition & 0 deletions packages/core/src/lib/floating/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ export {
type FloatingStyle,
} from './floating-style';

export * from './floating-size';
export { default as Floating } from './floating.svelte';
29 changes: 16 additions & 13 deletions packages/core/src/lib/select/searchable-select.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Select an option from a list, with search
-->
<script lang="ts">
import cx from 'classnames';
import { Floating } from '$lib/floating';
import { Floating, matchWidth } from '$lib/floating';
import { Icon } from '$lib/icon';
import { InputStates, type InputState } from '$lib/input';
import { createHandleKey } from '$lib/keyboard';
Expand Down Expand Up @@ -209,9 +209,10 @@ const handleKeydown = createHandleKey({
bind:value
/>
<Floating
matchWidth
offset={4}
referenceElement={inputElement}
size={matchWidth}
auto
>
<ul
id={LIST_ID}
Expand Down Expand Up @@ -241,7 +242,7 @@ const handleKeydown = createHandleKey({
? [otherOptionPrefix, option].filter(Boolean).join(' ')
: option}
class={cx(
'flex h-7.5 w-full cursor-pointer items-center justify-start text-ellipsis whitespace-nowrap px-2.5 text-xs',
'flex h-7.5 w-full cursor-pointer items-center justify-start px-2.5 text-xs',
isSelected ? 'bg-light' : 'hover:bg-light'
)}
on:pointerdown|preventDefault
Expand All @@ -251,19 +252,21 @@ const handleKeydown = createHandleKey({
>
{#if isOther}
<Icon
cx="mr-1 text-gray-6"
cx="mr-1 shrink-0 text-gray-6"
name="plus"
/>
{/if}
{#if highlight !== undefined}
<span class="whitespace-pre">{highlight[0]}</span>
<span class="whitespace-pre bg-yellow-100">{highlight[1]}</span>
<span class="whitespace-pre">{highlight[2]}</span>
{:else if isOther && otherOptionPrefix}
{otherOptionPrefix} {option}
{:else}
{option}
{/if}
<p class="truncate">
{#if highlight !== undefined}
<span class="whitespace-pre">{highlight[0]}</span>
<span class="whitespace-pre bg-yellow-100">{highlight[1]}</span>
<span class="whitespace-pre">{highlight[2]}</span>
{:else if isOther && otherOptionPrefix}
{otherOptionPrefix} {option}
{:else}
{option}
{/if}
</p>
</li>
{/each}
<slot />
Expand Down
7 changes: 6 additions & 1 deletion packages/core/src/lib/tooltip/tooltip-styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,12 @@ const createContext = (): TooltipContext => {
},
false
);
const style = floatingStyle({ offset: 7, shift: 5, flip: true, auto: true });
const style = floatingStyle({
offset: 7,
shift: { padding: 5 },
flip: { fallbackAxisSideDirection: 'start', crossAxis: false },
auto: true,
});

return {
id,
Expand Down
7 changes: 6 additions & 1 deletion packages/core/src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -1246,7 +1246,12 @@ const onHoverDelayMsInput = (event: Event) => {
<div class="flex gap-4">
<SearchableSelect
exclusive
options={['First Option', 'Option 2', 'C.) Option']}
options={[
'First Option',
'Option 2',
'C.) Option',
'A really long forth option just in case you need it',
]}
placeholder="Select an option"
onChange={(value) => {
// eslint-disable-next-line no-console
Expand Down

0 comments on commit fa44161

Please sign in to comment.