Skip to content

Conversation

@wuyiping0628
Copy link
Collaborator

@wuyiping0628 wuyiping0628 commented Nov 21, 2025

PR

PR Checklist

Please check if your PR fulfills the following requirements:

  • The commit message follows our Commit Message Guidelines
  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been added / updated (for bug fixes / features)

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • Other... Please describe:

What is the current behavior?

Issue Number: N/A

What is the new behavior?

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

Summary by CodeRabbit

  • New Features

    • Mobile-first mode for select components
    • Auto-select support for remote data
    • New props: initial label, tooltip config, show-empty-value, dropdown height, stop-propagation, max tag width, auto-select
  • Improvements

    • Better searchable/filterable behavior across mobile and desktop
    • Improved hover handling for non‑iOS devices
    • Dropdown/icon and loading presentation tweaks
  • Tests

    • UI tests updated to use input/root clicks and adjusted post-selection expectations

✏️ Tip: You can customize this high-level summary in your review settings.

@github-actions github-actions bot added the enhancement New feature or request (功能增强) label Nov 21, 2025
@coderabbitai
Copy link

coderabbitai bot commented Nov 21, 2025

Walkthrough

Mobile-first and searchable-aware behavior was added to base-select: public functions now accept designConfig and isMobileFirstMode, new exports and state (currentSizeMap, auto-select watcher, onMouseenterSelf) were introduced, component props were extended, icons/ref bindings refactored, and tests updated to use input-root click triggers.

Changes

Cohort / File(s) Summary
Renderless core
packages/renderless/src/base-select/index.ts
Expanded function signatures to accept isMobileFirstMode and designConfig; added exports computedCurrentSizeMap, watchOptionsWhenAutoSelect, onMouseenterSelf; broadened filterable checks to include props.searchable; updated computed helpers for mobile/searchable modes.
Renderless Vue integration
packages/renderless/src/base-select/vue.ts
Propagated isMobileFirstMode and injected isIOS; added state fields (currentSizeMap, rootAutoTipConfig, willFocusRun, willFocusTimer, designConfig); exposed computedCurrentSizeMap and watchOptionsWhenAutoSelect; wired auto-select watcher for remote options.
Component props & API
packages/vue/src/base-select/src/index.ts
Added props: initLabel, tooltipConfig, showEmptyValue, dropdownHeight, stopPropagation, maxTagWidth, autoSelect; changed dropdownIcon default to ''; removed IconChevronDown import.
Base-select template & icons
packages/vue/src/base-select/src/pc.vue
Replaced direct icon imports with function bindings (IconCloseiconClose, etc.); added AutoTip directive; switched state.selectDisabledstate.isDisabled; integrated tooltipConfig, maxTagWidth, and configurable loading icon; header uses onMouseenterSelf.
Select searchable handler
packages/vue/src/select/src/pc.vue
Updated searchable TinyInput update:modelValue to call handleQueryChange(state.query, false, true) (extra boolean args).
Tests (PC demos)
examples/sites/demos/pc/app/*.spec.ts
Adjusted test interactions to click the select root/input instead of input suffix icon; removed two SVG fill expectations; updated final searchable test expectation to preserve input value.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant VueComponent
    participant RenderlessAPI
    participant State

    User->>VueComponent: click / type / hover
    VueComponent->>RenderlessAPI: toggleMenu(e, designConfig)
    RenderlessAPI->>State: evaluate isMobileFirstMode + (filterable || searchable)
    alt mobile-first
        RenderlessAPI->>VueComponent: early-return or mobile UI flow
    else desktop
        RenderlessAPI->>State: normal visibility/focus logic
    end
    RenderlessAPI->>State: update model, emitChange(isMobileFirstMode)
    State-->>VueComponent: updated props/state
    VueComponent->>User: render updated UI
Loading
sequenceDiagram
    participant OptionsWatcher
    participant API
    participant Component

    OptionsWatcher->>API: options changed (remote)
    alt autoSelect enabled
        API->>Component: auto-update modelValue
        Component->>Component: re-render selection
    else autoSelect disabled
        OptionsWatcher-->>Component: no auto-selection
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Areas needing extra attention:

  • packages/renderless/src/base-select/index.ts: many signature changes and mobile/search branching.
  • packages/renderless/src/base-select/vue.ts: state additions and watcher wiring (autoSelect).
  • packages/vue/src/base-select/src/pc.vue: icon refactor, directive integration, prop usages.
  • tests in examples: ensure event targets and expectations align with runtime behavior.

Suggested reviewers

  • zzcr

Poem

🐰 I hopped through props and toggled a menu,
search and mobile-first stitched into view,
icons re-bound, tooltips now sing,
auto-select hums as the options spring,
a tiny rabbit cheers: the select feels new! 🥕

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main objective: synchronizing select component code to the base-select component, which aligns with the substantial changes across multiple base-select related files (renderless, vue, and component files).
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch wyp/search-select-1114

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2fff901 and e35e6d7.

📒 Files selected for processing (6)
  • examples/sites/demos/pc/app/base-select/all-text.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/base-select/basic-usage.spec.ts (2 hunks)
  • examples/sites/demos/pc/app/base-select/clearable.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/base-select/input-box-type.spec.ts (0 hunks)
  • examples/sites/demos/pc/app/base-select/multiple.spec.ts (1 hunks)
  • examples/sites/demos/pc/app/base-select/searchable.spec.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • examples/sites/demos/pc/app/base-select/input-box-type.spec.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: PR E2E Test (pnpm test:e2e3)
🔇 Additional comments (6)
examples/sites/demos/pc/app/base-select/basic-usage.spec.ts (1)

15-15: LGTM! Interaction pattern simplified.

The test now clicks the input element directly to reopen the dropdown instead of targeting the suffix icon. This is a more intuitive interaction pattern that aligns with typical user behavior.

Also applies to: 38-38

examples/sites/demos/pc/app/base-select/all-text.spec.ts (2)

11-11: LGTM! Simplified interaction pattern.

Clicking the select element directly is more straightforward than targeting the inner suffix element.


7-7: No issues found. The .nth(0) removal is justified.

Verification confirms that both demo files (all-text.vue and all-text-composition-api.vue) contain exactly one .tiny-base-select element. The test uses a scoped selector (wrap.locator('.tiny-base-select')) within the #all-text container, making the removal of .nth(0) safe and appropriate. No test flakiness risk exists.

examples/sites/demos/pc/app/base-select/clearable.spec.ts (1)

18-18: LGTM! Clearer test intent.

After clearing the value, clicking the input element to reopen the dropdown is more intuitive than clicking the icon. This change better distinguishes between the clear action (icon) and the reopen action (input).

examples/sites/demos/pc/app/base-select/multiple.spec.ts (1)

13-13: LGTM! Consistent interaction pattern.

The change from clicking the suffix element to clicking the select element directly aligns with the interaction pattern updates across all other test files. This provides a more consistent and maintainable test suite.

examples/sites/demos/pc/app/base-select/searchable.spec.ts (1)

32-32: No issues found — the behavior is intentional and consistent.

The searchable input retaining the search term ('上海') after selection is the intended design of the base-select component. This behavior is:

  1. Consistent across components: Both base-select and select implement identical searchable behavior (line 32 in both test files expects toHaveValue('上海'))
  2. Intentional design: This behavior was established when the feature was introduced (commit 0778e60) and has remained unchanged
  3. Already tested: The expectation in the test accurately reflects the component's designed behavior

The code change is correct and aligns with the component library's design.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
packages/renderless/src/base-select/vue.ts (1)

361-377: Pass designConfig into toggleMenu instead of isMobileFirstMode

In initApi, toggleMenu is currently initialized as:

toggleMenu: toggleMenu({ vm, state, props, api, isMobileFirstMode }),

but in packages/renderless/src/base-select/index.ts the signature is:

export const toggleMenu =
  ({ vm, state, props, api, designConfig }) => (e) => { ... }

Inside toggleMenu, designConfig is used (e.g. designConfig?.props?.stopPropagation), so passing isMobileFirstMode here leaves designConfig undefined and effectively disables the design-level stopPropagation default.

Update the call to:

-    toggleMenu: toggleMenu({ vm, state, props, api, isMobileFirstMode }),
+    toggleMenu: toggleMenu({ vm, state, props, api, designConfig }),

to align with the new signature and make stopPropagation work with designConfig.

packages/renderless/src/base-select/index.ts (1)

365-408: Bug in toggleCheckAll filtered-uncheck branch (value overwritten to union)

In the filtered “select all” case:

if (filtered) {
  if (state.filteredSelectCls === 'check' || state.filteredSelectCls === 'halfselect') {
    value = [...new Set([...state.modelValue, ...enabledValues])]
  } else {
    value = state.modelValue.filter((val) => !enabledValues.includes(val))
    // 避免编译报错
    value = Array.from(new Set([...state.modelValue, ...enabledValues]))
  }
}

The else branch is supposed to uncheck all currently enabled filtered options (i.e. remove enabledValues from state.modelValue). However, value is immediately overwritten with the union new Set([...state.modelValue, ...enabledValues]), so the “uncheck” operation never happens—no values are removed.

This breaks the UX for toggling “全选(筛选后)” off.

A minimal fix is to remove the second assignment:

-    } else {
-      value = state.modelValue.filter((val) => !enabledValues.includes(val))
-      // 避免编译报错
-      value = Array.from(new Set([...state.modelValue, ...enabledValues]))
-    }
+    } else {
+      // When already fully selected, uncheck the filtered items
+      value = state.modelValue.filter((val) => !enabledValues.includes(val))
+    }

If the original comment was addressing a specific compile-time issue, we should tackle that differently (e.g. ensuring value is always assigned before use) rather than reassigning it to the opposite value.

🧹 Nitpick comments (4)
packages/vue/src/select/src/pc.vue (1)

389-396: Use $event in @update:modelValue instead of state.query

Relying on state.query inside the @update:modelValue handler depends on Vue’s internal handler ordering with v-model. It’s safer and clearer to use the emitted value:

-            @update:modelValue="handleQueryChange(state.query, false, true)"
+            @update:modelValue="(val) => handleQueryChange(val, false, true)"

This avoids any timing issues between the v-model assignment and the handler execution.

packages/renderless/src/base-select/vue.ts (1)

568-589: Auto-select watcher wiring is reasonable but only reacts to array reference changes

The new watchers:

watch(() => state.options, api.watchOptionsWhenAutoSelect)
props.options && watch(() => props.options, api.watchOptionsWhenAutoSelect)

will only fire when state.options/props.options references change, not when items are pushed/spliced in-place. If remote data is typically replaced (this.options = [...]) this is fine; if it is mutated in-place, autoSelect may never trigger.

If in-place mutation is common in this codebase, consider mirroring watchOptions and using a shallow copy:

-  watch(() => state.options, api.watchOptionsWhenAutoSelect)
+  watch(() => [...state.options], api.watchOptionsWhenAutoSelect)

(and similarly for props.options if needed).

packages/vue/src/base-select/src/pc.vue (2)

389-396: Align @update:modelValue handler with emitted value

Same as in select/src/pc.vue, this searchable input uses:

@update:modelValue="handleQueryChange(state.query, false, true)"

This couples behavior to the v-model update order. Prefer using the emitted value:

-            @update:modelValue="handleQueryChange(state.query, false, true)"
+            @update:modelValue="(val) => handleQueryChange(val, false, true)"

for clearer and safer behavior.


471-477: Loading block always renders spinner component, even when not loading

In the empty/loading section:

<div v-else class="tiny-select-dropdown__loading" :class="{ 'show-loading-icon': loading }">
  <template v-if="!loading">
    <!-- empty image/text -->
  </template>
  <component
    class="circular"
    :is="(state.designConfig && state.designConfig.icons && state.designConfig.icons.loadingIcon) || 'icon-loading-shadow'"
  ></component>
</div>

the spinner <component> is rendered regardless of loading. In select/src/pc.vue, the spinner is guarded with v-if="loading" and the empty text is inside the v-else branch, which avoids rendering the spinner when not loading.

For visual and behavioral consistency, consider:

-            <div v-else class="tiny-select-dropdown__loading" :class="{ 'show-loading-icon': loading }">
-              <template v-if="!loading">
-                <span v-if="showEmptyImage" class="tiny-select-dropdown__empty-images"></span>
-                <span v-else class="tiny-select-dropdown__empty"> {{ state.emptyText }}</span>
-              </template>
-              <component
-                class="circular"
-                :is="
-                  (state.designConfig && state.designConfig.icons && state.designConfig.icons.loadingIcon) ||
-                  'icon-loading-shadow'
-                "
-              ></component>
-            </div>
+            <div v-else class="tiny-select-dropdown__loading" :class="{ 'show-loading-icon': loading }">
+              <component
+                v-if="loading"
+                class="circular"
+                :is="
+                  (state.designConfig && state.designConfig.icons && state.designConfig.icons.loadingIcon) ||
+                  'icon-loading-shadow'
+                "
+              ></component>
+              <template v-else>
+                <span v-if="showEmptyImage" class="tiny-select-dropdown__empty-images"></span>
+                <span v-else class="tiny-select-dropdown__empty"> {{ state.emptyText }}</span>
+              </template>
+            </div>

to match the select component and avoid showing (or needing to hide) a spinner when not loading.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2eafe0c and 2fff901.

📒 Files selected for processing (5)
  • packages/renderless/src/base-select/index.ts (36 hunks)
  • packages/renderless/src/base-select/vue.ts (13 hunks)
  • packages/vue/src/base-select/src/index.ts (3 hunks)
  • packages/vue/src/base-select/src/pc.vue (20 hunks)
  • packages/vue/src/select/src/pc.vue (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2024-11-25T03:43:05.285Z
Learnt from: Davont
Repo: opentiny/tiny-vue PR: 2513
File: packages/vue/src/huicharts/huicharts-histogram/src/chart-histogram.vue:33-36
Timestamp: 2024-11-25T03:43:05.285Z
Learning: 在 Tiny Vue 代码库中,使用 `chart-core` 中的 `huiChartOption` 的组件,不应在其 `data` 中定义 `huiChartOption` 或 `option`,而是应该依赖 `chart-core` 提供的 `huiChartOption`。

Applied to files:

  • packages/vue/src/base-select/src/index.ts
  • packages/vue/src/base-select/src/pc.vue
🧬 Code graph analysis (2)
packages/renderless/src/base-select/vue.ts (2)
packages/vue-hooks/src/useUserAgent.ts (1)
  • useUserAgent (15-18)
packages/renderless/src/base-select/index.ts (10)
  • emitChange (185-193)
  • directEmitChange (195-201)
  • toggleMenu (761-795)
  • setSoftFocus (718-736)
  • onMouseenterSelf (1502-1509)
  • updateModelValue (1827-1837)
  • computedReadonly (1884-1898)
  • computedShowNewOption (1913-1923)
  • computedCurrentSizeMap (1676-1683)
  • watchOptionsWhenAutoSelect (1365-1378)
packages/renderless/src/base-select/index.ts (1)
packages/renderless/src/option/index.ts (1)
  • escapeRegexpString (15-15)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: PR E2E Test (pnpm test:e2e3)
🔇 Additional comments (17)
packages/renderless/src/base-select/vue.ts (1)

167-283: New state fields for display-only content, sizing, and AutoTip look consistent

The additions in initState/initStateAdd (isIOS, displayOnlyContent, currentSizeMap, rootAutoTipConfig, focus timers, etc.) are coherent with the renderless/index.ts exports and vue-layer usage (e.g. AutoTip and display-only tooltip behavior). No functional issues spotted in this block.

packages/vue/src/base-select/src/pc.vue (5)

78-115: Tag tooltip and width enhancements look correct

Using isTagClosable, state.isDisabled, maxTagWidth, and tooltipConfig (effect/placement/popper-class) on the collapsed first tag is consistent with the renderless API and mirrors the select component. No issues spotted with these bindings.


219-225: Display-only multi-select text now honors state.isDisabled

The updated display-only span correctly adds the 'is-disabled' class based on state.isDisabled, matching the root disabled semantics. This is a good alignment with the common disabled handling.


260-285: tiny-input flags and classes now consistent with extended props

The additions:

  • :showTooltip="false"
  • :show-empty-value="showEmptyValue"
  • class flags 'is-show-close', 'show-copy', 'show-clear'

are consistent with the new props from base-select/index.ts and with the select component’s behavior. No functional problems here.


569-651: Directive and icon registration matches new renderless and icon APIs

Adding AutoTip to directives and switching icons to the icon*() factories (IconClose, IconCopy, IconHalfselect, IconCheck, IconCheckedSur, IconSearch, IconDownWard, IconEllipsis, IconChevronUp) is consistent with the updated renderless/base-select and icon packages. Component registration looks correct and complete.


724-742: New props exposure (initLabel, tooltipConfig, showEmptyValue, stopPropagation, allText, maxTagWidth) is aligned with base-select API

These props mirror the definitions in packages/vue/src/base-select/src/index.ts and are all actually consumed in the template or renderless logic (e.g. initLabel/initLabel handling, tooltipConfig, showEmptyValue, stopPropagation in toggleMenu, allText and maxTagWidth in tags). No issues with the public API surface here.

packages/renderless/src/base-select/index.ts (11)

83-94: Regex escaping in queryChange correctly handles special characters

Using escapeRegexpString in:

const filterDatas = state.initDatas.filter((item) =>
  new RegExp(escapeRegexpString(value), 'i').test(item[props.textField])
)

is a good hardening against user-entered regex metacharacters causing errors or unintended matches. This looks correct and safe.


120-162: handleQueryChange extension to searchable and disabled checks is sound

The updated guard:

if (
  props.multiple &&
  (props.filterable || props.searchable) &&
  !props.shape &&
  !state.selectDisabled
) {
  nextTick(() => {
    const length = vm.$refs.input.value.length * 15 + 20
    state.inputLength = state.collapseTags ? Math.min(50, length) : length
    api.managePlaceholder()
    api.resetInputHeight()
  })
}

correctly generalizes from filterable to (filterable || searchable) and respects state.selectDisabled so we don’t mutate input geometry when disabled/display-only. No issues here.


185-193: Mobile-first change emission guard (emitChange) looks correct

The new emitChange wrapper:

export const emitChange =
  ({ emit, props, state, constants, isMobileFirstMode }) =>
  (value, changed) => {
    if (isMobileFirstMode && state.device === 'mb' && props.multiple && !changed) return

    if (!isEqual(props.modelValue, state.compareValue)) {
      emit('change', value)
    }
  }

matches the mobile-first requirement to avoid emitting redundant change events in mobile multiple-select mode unless explicitly marked as changed. The comparison vs state.compareValue preserves previous behavior; the early-return condition is scoped tightly enough to not affect non-mobile or single-select flows.


561-615: Resetting input height with currentSizeMap and spacing is consistent

The updated resetInputHeight:

  • Skips when collapseTags is on and neither filterable nor searchable are enabled.
  • Uses spacingHeight from designConfig with a sane default.
  • Bases height on Math.max(tagsClientHeight + spacingHeight, state.currentSizeMap) or state.currentSizeMap when no selection.

Together with computedCurrentSizeMap and the designConfig.state.sizeMap default fallbacks, this provides predictable sizing across themes and is aligned with the new sizing API. No issues detected.


1199-1229: postOperOfToVisible logic for initLabel and searchable is coherent

The new logic:

  • For multiple:
    • When props.modelValue and props.initLabel are set but state.selected is empty, it uses initLabel as selectedLabel.
  • For single:
    • Honors grid/tree vs normal renderType when setting selectedLabel.
    • Handles allowCreate + createdSelected for filterable/searchable.
    • Keeps state.query in sync when (filterable || searchable) is true.
    • Falls back to initLabel when modelValue is present but selectedLabel is empty.

This seems consistent with the new initLabel prop semantics and with searchable/filterable behavior.


1291-1333: watchVisible enhancements for searchable/mobile-first look correct

Key additions:

  • Blur reference input on close when (filterable || searchable || remote) to avoid lingering focus.
  • In mobile-first multiple mode, copy state.selected into state.selectedCopy on open for staging.
  • Keep existing updatePopper/scrollbar logic and shape === 'filter' softFocus reset.

These changes are coherent with the broader mobile-first design and do not introduce obvious regressions.


1650-1674: initQuery correctly generalizes to (filterable || searchable) for remote initialization

The isRemote flag:

const isRemote =
  (props.filterable || props.searchable) &&
  props.remote &&
  (typeof props.remoteMethod === 'function' || typeof props.initQuery === 'function')

properly includes searchable alongside filterable for remote initialization while preserving the original function-type checks. The promise handling for async initQuery also looks correct.


1676-1683: computedCurrentSizeMap and its use in sizing is well-structured

computedCurrentSizeMap:

export const computedCurrentSizeMap =
  ({ state, designConfig }) =>
  () => {
    const defaultSizeMap = { default: 32, mini: 24, small: 28, medium: 40 }
    const sizeMap = designConfig?.state?.sizeMap || defaultSizeMap

    return sizeMap[state.selectSize || 'default']
  }

provides a clean extension point for theme-driven sizing via designConfig.state.sizeMap with sensible defaults and integrates neatly with resetInputHeight.


1884-1898: computedReadonly’s iOS/mobile-first/searchable logic is coherent

The new implementation:

  • Special-cases iOS + props.filterable to always return false (input editable), working around platform quirks.
  • Otherwise returns true when:
    • mobile-first + device is mb, or
    • props.readonly, or
    • neither filterable nor searchable are enabled, or
    • props.multiple, or
    • modern browsers with dropdown closed.

This looks intentional and consistent with the mobile-first and searchable requirements.


1933-1945: computedDisabledTooltipContent and computedSelectDisabled align with display-only semantics

These computations:

export const computedDisabledTooltipContent =
  ({ state }) =>
  () => state.displayOnlyContent

export const computedSelectDisabled =
  ({ state }) =>
  () => state.isDisabled || state.isDisplayOnly

tie the disabled tooltip text directly to the display-only content and centralize the notion of “select-disabled” as either disabled or display-only. This matches the new displayOnlyContent and isDisabled state fields and simplifies template logic.


2046-2049: handleDebouncedQueryChange correctly passes isInput=true

Changing the debounce callback to:

debounce(state.debounce, (value) => {
  api.handleQueryChange(value, false, true)
})

ensures isInput is correctly set when debounced queries are triggered, which is important for the optimization path that only runs when isInput is true.

@wuyiping0628 wuyiping0628 changed the title feat(base-select): [base-select] Synchronize the select component code to the base-select component feat(base-select): [base-select] Synchronize the select component code to the base-select component Nov 24, 2025
@kagol kagol merged commit fd3c1b1 into dev Nov 24, 2025
7 of 10 checks passed
@kagol kagol deleted the wyp/search-select-1114 branch November 24, 2025 02:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request (功能增强)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants