Skip to content

Commit

Permalink
Move hold prop to the Combobox Options (#1109)
Browse files Browse the repository at this point in the history
* move `hold` prop to the `Combobox Options`

* update changelog
  • Loading branch information
RobinMalfait authored Feb 16, 2022
1 parent 0bf325d commit 53af7fa
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 27 deletions.
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Add `Combobox` component ([#1047](https://github.com/tailwindlabs/headlessui/pull/1047), [#1099](https://github.com/tailwindlabs/headlessui/pull/1099), [#1101](https://github.com/tailwindlabs/headlessui/pull/1101), [#1104](https://github.com/tailwindlabs/headlessui/pull/1104))
- Add `Combobox` component ([#1047](https://github.com/tailwindlabs/headlessui/pull/1047), [#1099](https://github.com/tailwindlabs/headlessui/pull/1099), [#1101](https://github.com/tailwindlabs/headlessui/pull/1101), [#1104](https://github.com/tailwindlabs/headlessui/pull/1104), [#1109](https://github.com/tailwindlabs/headlessui/pull/1109))

## [Unreleased - @headlessui/vue]

Expand All @@ -32,7 +32,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Add `Combobox` component ([#1047](https://github.com/tailwindlabs/headlessui/pull/1047), [#1099](https://github.com/tailwindlabs/headlessui/pull/1099), [#1101](https://github.com/tailwindlabs/headlessui/pull/1101), [#1104](https://github.com/tailwindlabs/headlessui/pull/1104), [#1106](https://github.com/tailwindlabs/headlessui/pull/1106))
- Add `Combobox` component ([#1047](https://github.com/tailwindlabs/headlessui/pull/1047), [#1099](https://github.com/tailwindlabs/headlessui/pull/1099), [#1101](https://github.com/tailwindlabs/headlessui/pull/1101), [#1104](https://github.com/tailwindlabs/headlessui/pull/1104), [#1106](https://github.com/tailwindlabs/headlessui/pull/1106), [#1109](https://github.com/tailwindlabs/headlessui/pull/1109))

## [@headlessui/react@v1.4.3] - 2022-01-14

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4269,10 +4269,10 @@ describe('Mouse interactions', () => {
'should be possible to hold the last active option',
suppressConsoleLogs(async () => {
render(
<Combobox value="test" onChange={console.log} hold>
<Combobox value="test" onChange={console.log}>
<Combobox.Input onChange={NOOP} />
<Combobox.Button>Trigger</Combobox.Button>
<Combobox.Options>
<Combobox.Options hold>
<Combobox.Option value="a">Option A</Combobox.Option>
<Combobox.Option value="b">Option B</Combobox.Option>
<Combobox.Option value="c">Option C</Combobox.Option>
Expand Down
28 changes: 16 additions & 12 deletions packages/@headlessui-react/src/components/combobox/combobox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,13 @@ interface StateDefinition {
comboboxPropsRef: MutableRefObject<{
value: unknown
onChange(value: unknown): void
hold: boolean
}>
inputPropsRef: MutableRefObject<{
displayValue?(item: unknown): string
}>
optionsPropsRef: MutableRefObject<{
static: boolean
hold: boolean
}>
labelRef: MutableRefObject<HTMLLabelElement | null>
inputRef: MutableRefObject<HTMLInputElement | null>
Expand Down Expand Up @@ -230,22 +230,23 @@ let ComboboxRoot = forwardRefWithAs(function Combobox<
TTag extends ElementType = typeof DEFAULT_COMBOBOX_TAG,
TType = string
>(
props: Props<TTag, ComboboxRenderPropArg<TType>, 'value' | 'onChange' | 'disabled' | 'hold'> & {
props: Props<TTag, ComboboxRenderPropArg<TType>, 'value' | 'onChange' | 'disabled'> & {
value: TType
onChange(value: TType): void
disabled?: boolean
hold?: boolean
},
ref: Ref<TTag>
) {
let { value, onChange, disabled = false, hold = false, ...passThroughProps } = props
let { value, onChange, disabled = false, ...passThroughProps } = props

let comboboxPropsRef = useRef<StateDefinition['comboboxPropsRef']['current']>({
value,
onChange,
hold,
})
let optionsPropsRef = useRef<StateDefinition['optionsPropsRef']['current']>({ static: false })
let optionsPropsRef = useRef<StateDefinition['optionsPropsRef']['current']>({
static: false,
hold: false,
})
let inputPropsRef = useRef<StateDefinition['inputPropsRef']['current']>({
displayValue: undefined,
})
Expand All @@ -272,9 +273,6 @@ let ComboboxRoot = forwardRefWithAs(function Combobox<
useIsoMorphicEffect(() => {
comboboxPropsRef.current.onChange = onChange
}, [onChange, comboboxPropsRef])
useIsoMorphicEffect(() => {
comboboxPropsRef.current.hold = hold
}, [hold, comboboxPropsRef])

useIsoMorphicEffect(() => dispatch({ type: ActionTypes.SetDisabled, disabled }), [disabled])

Expand Down Expand Up @@ -710,6 +708,7 @@ interface OptionsRenderPropArg {
type OptionsPropsWeControl =
| 'aria-activedescendant'
| 'aria-labelledby'
| 'hold'
| 'id'
| 'onKeyDown'
| 'role'
Expand All @@ -721,9 +720,12 @@ let Options = forwardRefWithAs(function Options<
TTag extends ElementType = typeof DEFAULT_OPTIONS_TAG
>(
props: Props<TTag, OptionsRenderPropArg, OptionsPropsWeControl> &
PropsForFeatures<typeof OptionsRenderFeatures>,
PropsForFeatures<typeof OptionsRenderFeatures> & {
hold?: boolean
},
ref: Ref<HTMLUListElement>
) {
let { hold = false, ...passthroughProps } = props
let [state] = useComboboxContext('Combobox.Options')
let { optionsPropsRef } = state

Expand All @@ -743,6 +745,9 @@ let Options = forwardRefWithAs(function Options<
useIsoMorphicEffect(() => {
optionsPropsRef.current.static = props.static ?? false
}, [optionsPropsRef, props.static])
useIsoMorphicEffect(() => {
optionsPropsRef.current.hold = hold
}, [hold, optionsPropsRef])

useTreeWalker({
container: state.optionsRef.current,
Expand Down Expand Up @@ -774,7 +779,6 @@ let Options = forwardRefWithAs(function Options<
id,
ref: optionsRef,
}
let passthroughProps = props

return render({
props: { ...passthroughProps, ...propsWeControl },
Expand Down Expand Up @@ -880,7 +884,7 @@ function Option<
let handleLeave = useCallback(() => {
if (disabled) return
if (!active) return
if (state.comboboxPropsRef.current.hold) return
if (state.optionsPropsRef.current.hold) return
dispatch({ type: ActionTypes.GoToOption, focus: Focus.Nothing })
}, [disabled, active, dispatch, state.comboboxState, state.comboboxPropsRef])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4491,10 +4491,10 @@ describe('Mouse interactions', () => {
suppressConsoleLogs(async () => {
renderTemplate({
template: html`
<Combobox v-model="value" hold>
<Combobox v-model="value">
<ComboboxInput />
<ComboboxButton>Trigger</ComboboxButton>
<ComboboxOptions>
<ComboboxOptions hold>
<ComboboxOption value="a">Option A</ComboboxOption>
<ComboboxOption value="b">Option B</ComboboxOption>
<ComboboxOption value="c">Option C</ComboboxOption>
Expand Down
19 changes: 10 additions & 9 deletions packages/@headlessui-vue/src/components/combobox/combobox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,9 @@ type StateDefinition = {
// State
comboboxState: Ref<ComboboxStates>
value: ComputedRef<unknown>
hold: ComputedRef<Boolean>

inputPropsRef: Ref<{ displayValue?: (item: unknown) => string }>
optionsPropsRef: Ref<{ static: boolean }>
optionsPropsRef: Ref<{ static: boolean; hold: boolean }>

labelRef: Ref<HTMLLabelElement | null>
inputRef: Ref<HTMLInputElement | null>
Expand Down Expand Up @@ -85,7 +84,6 @@ export let Combobox = defineComponent({
as: { type: [Object, String], default: 'template' },
disabled: { type: [Boolean], default: false },
modelValue: { type: [Object, String, Number, Boolean] },
hold: { type: [Boolean], default: false },
},
setup(props, { slots, attrs, emit }) {
let comboboxState = ref<StateDefinition['comboboxState']['value']>(ComboboxStates.Closed)
Expand All @@ -97,17 +95,16 @@ export let Combobox = defineComponent({
) as StateDefinition['optionsRef']
let optionsPropsRef = ref<StateDefinition['optionsPropsRef']['value']>({
static: false,
hold: false,
}) as StateDefinition['optionsPropsRef']
let options = ref<StateDefinition['options']['value']>([])
let activeOptionIndex = ref<StateDefinition['activeOptionIndex']['value']>(null)

let value = computed(() => props.modelValue)
let hold = computed(() => props.hold)

let api = {
comboboxState,
value,
hold,
inputRef,
labelRef,
buttonRef,
Expand Down Expand Up @@ -260,7 +257,7 @@ export let Combobox = defineComponent({
}

return render({
props: omit(props, ['modelValue', 'onUpdate:modelValue', 'disabled', 'hold']),
props: omit(props, ['modelValue', 'onUpdate:modelValue', 'disabled']),
slot,
slots,
attrs,
Expand Down Expand Up @@ -545,12 +542,16 @@ export let ComboboxOptions = defineComponent({
as: { type: [Object, String], default: 'ul' },
static: { type: Boolean, default: false },
unmount: { type: Boolean, default: true },
hold: { type: [Boolean], default: false },
},
setup(props, { attrs, slots }) {
let api = useComboboxContext('ComboboxOptions')
let id = `headlessui-combobox-options-${useId()}`
watchEffect(() => {
api.optionsPropsRef.value.static = props.static ?? false
api.optionsPropsRef.value.static = props.static
})
watchEffect(() => {
api.optionsPropsRef.value.hold = props.hold
})
let usesOpenClosedState = useOpenClosed()
let visible = computed(() => {
Expand Down Expand Up @@ -586,7 +587,7 @@ export let ComboboxOptions = defineComponent({
ref: api.optionsRef,
role: 'listbox',
}
let passThroughProps = props
let passThroughProps = omit(props, ['hold'])

return render({
props: { ...passThroughProps, ...propsWeControl },
Expand Down Expand Up @@ -667,7 +668,7 @@ export let ComboboxOption = defineComponent({
function handleLeave() {
if (props.disabled) return
if (!active.value) return
if (api.hold.value) return
if (api.optionsPropsRef.value.hold) return
api.goToOption(Focus.Nothing)
}

Expand Down

0 comments on commit 53af7fa

Please sign in to comment.