Skip to content

Conversation

@discreted66
Copy link
Collaborator

@discreted66 discreted66 commented Dec 5, 2025

PR

feat:select-wrapper多端示例以及文档

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

  • Documentation
    • Added comprehensive demo examples showcasing Select component features including basic usage, multi-select, remote search, filtering, grouping, grid rendering, tree rendering, caching, and custom slots.
    • Added component documentation with English and Chinese guides.

✏️ 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 Dec 5, 2025
@coderabbitai
Copy link

coderabbitai bot commented Dec 5, 2025

Walkthrough

Adds 46+ new Vue demo components showcasing various configurations and use cases of the TinySelect wrapper component (single-select, multi-select, grid-based, tree-based, remote search, filtering, custom slots, and event handling) across the mobile-first demo site, plus documentation files and configuration metadata.

Changes

Cohort / File(s) Summary
Basic & Single-Select Demos
basic-usage.vue, native-properties.vue, clearable.vue, size.vue, hide-drop.vue, filter-mode.vue, is-drop-inherit-width.vue, show-alloption.vue, tag-type.vue
Core select demos featuring basic configurations: label-based options, native HTML placeholder, clearable state, size variants, dropdown visibility control, filter modes, width inheritance, and tag styling.
Multi-Select & Tag Handling
multiple.vue, collapse-tags.vue, copy-multi.vue, show-tip.vue, all-text.vue
Multi-select scenarios demonstrating tag management: collapsible tag display, copy-to-clipboard functionality, overflow tooltip handling, and all-text label customization.
Advanced Selection Features
allow-create.vue, binding-obj.vue, cache-usage.vue, clear-no-match-value.vue, memoize-usage.vue
Extended functionality: create new options dynamically, bind object values, cache selected values to localStorage, clear non-matching values, and memoize usage patterns.
Focus, Blur & Dropdown Behavior
automatic-dropdown.vue, manual-focus-blur.vue
Dropdown trigger and focus state management with programmatic and automatic control.
Filtering & Search
filter-method.vue, copy-single.vue, remote-method.vue, optimization.vue
Custom and remote filtering: default vs. custom filter functions, single-select copy with filterable/remote variants, remote method with async search, and large dataset (100K+ options) optimization.
Events & Interactions
events.vue, disabled.vue
Event handlers (change, clear, focus, blur, removeTag, visibleChange, dropdownClick) and disabled state configurations (disabled selects, disabled options, hover tooltips).
Grid-Based Rendering
nest-grid.vue, nest-grid-init-query.vue, nest-grid-remote.vue, nest-grid-disable.vue, nest-radio-grid-much-data.vue, map-field.vue, init-label.vue
Grid render mode: static/remote data grids, radio and checkbox selections, large datasets (800+ rows), field mapping, and initialization labels.
Tree & Hierarchical Selection
nest-tree.vue, extra-query-params.vue
Tree-style rendering with lazy loading and dependent/cascading select with extra query parameters.
Slot & Custom Rendering
slot-default.vue, slot-empty.vue, slot-header-footer.vue, slot-label.vue, slot-prefix.vue, slot-reference.vue
Custom template slots for option content, empty state, dropdown header/footer, labels with avatars, prefix icons, and reference icons.
Option Grouping
option-group.vue
Grouped options with filtering and multi-select support.
Popup & Position Styling
popup-style-position.vue
Dropdown positioning and custom popper styles.
Documentation & Configuration
webdoc/select-wrapper.cn.md, webdoc/select-wrapper.en.md, webdoc/select-wrapper.js
Chinese and English documentation files plus metadata/configuration object defining demos, features, and localized descriptions for the select-wrapper component.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

  • Rationale: The PR consists primarily of demo/example components with highly repetitive patterns (data initialization, option arrays, v-model bindings, basic styling). Each file contains minimal business logic—mostly template-driven UI demonstrations without complex state management or control-flow changes.
  • Areas for attention:
    • Verify consistency of option data structures across demos (value/label fields, disabled flags, etc.)
    • Confirm all imports from @opentiny/vue are correct and consistent
    • Check that scoped styles don't conflict and widths/spacing are uniform where intended
    • Validate that grid configurations (gridOp, gridOpRadio) have correct column definitions and data structure
    • Ensure remote method simulations (setTimeout, Promise resolution) follow the same pattern for clarity

Suggested reviewers

  • zzcr

Poem

A warren of selects, so neat and so tidy,
Multi-select, filter, and grid-views fine!
With slots and with slots, the UI grows wider,
Rabbits are hopping—these demos align! 🐰✨
Forty-six flavors of choice to define. 🎯

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 directly matches the main changeset: adding mobile-first example components and documentation for the select-wrapper component.
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

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: 16

🧹 Nitpick comments (28)
examples/sites/demos/mobile-first/app/select-wrapper/slot-empty.vue (1)

28-43: Consider more responsive width and optional click behavior for the reload button

For a mobile-first demo, a fixed 280px width on .tiny-select can look narrow or misaligned on some devices; consider width: 100% plus an optional max-width for better responsiveness. Also, since the button label suggests reloading, wiring a simple @click handler (even if it just logs or calls a stubbed reload() method) would make the example behavior more self-explanatory.

examples/sites/demos/mobile-first/app/select-wrapper/native-properties.vue (1)

1-34: Implementation is sound; consider minor template cleanup

The demo correctly wires v-model, placeholder, and option data into TinySelectWrapper/TinyOption, and the scoped width style is appropriate. As a tiny cosmetic tweak, since you rely solely on the label prop and don’t use slot content, you could self-close the option tag for readability:

-    <tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
+    <tiny-option
+      v-for="item in options"
+      :key="item.value"
+      :label="item.label"
+      :value="item.value"
+    />

Purely optional; behavior is already correct.

examples/sites/demos/mobile-first/app/select-wrapper/size.vue (2)

1-22: Template clearly demonstrates all size variants

The four tiny-select instances correctly showcase multiple mode for default, medium, small, and mini, all wired to appropriate v-model bindings and a shared options list. If you want to further polish the demo, you might optionally reorder the sections (e.g., 默认 → medium → small → mini) so readers see the default first, but this is not required.


49-57: Scoped styles are safe; spacing could optionally move from <br /> to CSS

The scoped .tiny-select width and p typography are minimal and low‑risk. For slightly cleaner markup, you could replace some of the repeated <br /> tags in the template with vertical spacing via CSS (e.g., margins on .tiny-select or p), but the current approach is acceptable for a simple demo.

examples/sites/demos/mobile-first/app/select-wrapper/init-label.vue (1)

70-73: Remove unused CSS rule.

The p tag selector is defined but no <p> element exists in the template.

Apply this diff to remove the unused rule:

 .tiny-select {
   width: 480px;
 }
-p {
-  font-size: 14px;
-  line-height: 1.5;
-}
examples/sites/demos/mobile-first/app/select-wrapper/collapse-tags.vue (2)

24-48: Optional: derive full-selection model from options to avoid drift

value3 repeats all option values manually. If the options list is edited (add/remove/reorder), it’s easy to forget to update value3. Consider deriving it from options so it always stays in sync.

For example:

 export default {
   components: {
     TinySelect,
     TinyOption
   },
-  data() {
-    return {
-      options: [
+  data() {
+    const options = [
       { value: '选项 1', label: '北京' },
       { value: '选项 2', label: '上海' },
       { value: '选项 3', label: '天津' },
       { value: '选项 4', label: '重庆超长超长超长超长超长超长超长超长超长' },
       { value: '选项 5', label: '深圳' },
       { value: '选项 6', label: '广州' },
       { value: '选项 7', label: '武汉' }
-      ],
-      value1: ['选项 1', '选项 2'],
-      value2: ['选项 1', '选项 2', '选项 3', '选项 4'],
-      value3: ['选项 1', '选项 2', '选项 3', '选项 4', '选项 5', '选项 6', '选项 7']
-    }
+    ]
+
+    return {
+      options,
+      value1: options.slice(0, 2).map((item) => item.value),
+      value2: options.slice(0, 4).map((item) => item.value),
+      value3: options.map((item) => item.value)
+    }
   }
 }

51-58: Optional: consider a more responsive width for mobile

A fixed width: 280px works for the demo but is a bit rigid on varying mobile widths. If you want this example to better reflect mobile-first behavior, you could make the select fill the container while capping its max width.

Example:

-.tiny-select {
-  width: 280px;
-}
+.tiny-select {
+  width: 100%;
+  max-width: 280px;
+}
examples/sites/demos/mobile-first/app/select-wrapper/optimization.vue (1)

25-37: Simplify and optimize generation of 100k options

Creating 100,000 options via JSON.parse on interpolated strings is unnecessary overhead (extra string allocations + parsing) and buildOptions() is re-run on every component instance. For an “optimization” example, it’s worth tightening this up.

You can both avoid JSON.parse and compute the options once at module scope:

-import { TinySelectWrapper as TinySelect, TinyModal } from '@opentiny/vue'
-
-const buildOptions = () =>
-  Array.from({ length: 100000 }).map((item, i) => JSON.parse(`{"value":"选项 ${i}","label":"北京 ${i}"}`))
+import { TinySelectWrapper as TinySelect, TinyModal } from '@opentiny/vue'
+
+const OPTIONS = Array.from({ length: 100000 }, (_, i) => ({
+  value: `选项 ${i}`,
+  label: `北京 ${i}`
+}))

 export default {
   components: {
     TinySelect
   },
   data() {
     return {
       value1: '',
       value2: [],
-      options: buildOptions()
+      options: OPTIONS
     }
   },

This keeps the behavior the same, but removes 100k JSON parses and repeated recomputation.

examples/sites/demos/mobile-first/app/select-wrapper/extra-query-params.vue (3)

115-121: Consider using .includes() for better readability.

The bitwise NOT operator (~) for indexOf checks is clever but can be confusing, especially in demo code meant to teach usage patterns.

     remoteMethod1(value) {
-      const parents = this.parents.filter((parent) => ~parent.label.indexOf(value || ''))
+      const parents = this.parents.filter((parent) => parent.label.includes(value || ''))

       return new Promise((resolve) => {
         resolve(parents)
       })
     },

Apply the same pattern to remoteMethod2 at line 134.


122-131: Unused init parameter.

The init parameter is documented but not used in the function body. Consider either demonstrating its usage or removing it to avoid confusion in this demo.


53-71: Consider consolidating data initialization.

The parents and children arrays are defined as empty in data() but populated in created(). For a demo file, initializing them directly in data() would be cleaner and easier to follow:

   data() {
     return {
-      parents: [],
-      children: [],
+      parents: [
+        { id: '001', label: '指南' },
+        { id: '002', label: '组件' }
+      ],
+      children: [
+        { id: '001', label: '安装', parent: '001' },
+        { id: '002', label: '开发', parent: '001' },
+        { id: '004', label: '框架风格', parent: '002' },
+        { id: '005', label: '表单组件', parent: '002' },
+        { id: '006', label: '数据组件', parent: '002' },
+        { id: '007', label: '提示组件', parent: '002' },
+        { id: '008', label: '导航组件', parent: '002' },
+        { id: '009', label: '其他组件', parent: '002' }
+      ],
       radioValue1: ['001'],
       radioValue2: ['001'],
       // ... rest unchanged
-      extraQueryParams: null
+      extraQueryParams: ['001']
     }
   },
-  created() {
-    this.parents = [...]
-    this.children = [...]
-    this.extraQueryParams = this.radioValue1
-  },

Then remove the created() hook entirely.

examples/sites/demos/mobile-first/app/select-wrapper/manual-focus-blur.vue (1)

9-11: Consider separate v-models per scenario to avoid shared selection state.

All three <tiny-select> instances are bound to the same value. That works functionally, but it may be surprising in a docs/demo context that choosing an option in one scenario changes the displayed selection in the others.

If you want each scenario to feel independent, you can give them their own models:

-      <tiny-select v-model="value" ref="drop1">
+      <tiny-select v-model="value1" ref="drop1">
@@
-      <tiny-select v-model="value" ref="drop2" filterable>
+      <tiny-select v-model="value2" ref="drop2" filterable>
@@
-      <tiny-select v-model="value" ref="drop3" automatic-dropdown>
+      <tiny-select v-model="value3" ref="drop3" automatic-dropdown>
   data() {
     return {
       options: [
@@
-      ],
-      value: ''
+      ],
+      value1: '',
+      value2: '',
+      value3: ''
     }
   },

The focus/blur handlers can stay as‑is; they don’t depend on the model value.

Also applies to: 20-22, 31-33, 49-57, 59-77

examples/sites/demos/mobile-first/app/select-wrapper/filter-method.vue (2)

5-5: Remove unused ref.

The ref="selectRef" is defined but never referenced in the script. Consider removing it to keep the code clean.


8-8: Unnecessary v-show directive.

The condition v-show="!item.filter" is always true because the options data (lines 48-54) doesn't include a filter property. This directive appears unnecessary and can be removed unless there's intended logic to set this property dynamically.

Also applies to: 28-28

examples/sites/demos/mobile-first/app/select-wrapper/copy-multi.vue (1)

1-41: Consider using CSS margins instead of multiple <br /> tags.

The template uses multiple <br /> tags for vertical spacing. While functional, CSS margins would be more maintainable and semantic.

For example, apply this diff to add spacing via CSS:

 <style lang="less" scoped>
 .tiny-select {
   width: 280px;
+  margin-bottom: 20px;
 }
 p {
   font-size: 14px;
   line-height: 1.5;
+  margin-top: 20px;
+  margin-bottom: 10px;
 }
 </style>

Then remove the extraneous <br /> tags from the template.

examples/sites/demos/mobile-first/app/select-wrapper/option-group.vue (1)

6-7: Consider more robust keys for option groups

Groups are keyed only by group.label in the v-for:

<tiny-option-group v-for="group in options3" :key="group.label" ...>

If more groups are added later with the same label, this can cause non-unique keys and patching glitches. Consider including the index for uniqueness:

-      <tiny-option-group v-for="group in options3" :key="group.label" :label="group.label" :disabled="!!group.disabled">
+      <tiny-option-group
+        v-for="(group, gIndex) in options3"
+        :key="`${group.label}-${gIndex}`"
+        :label="group.label"
+        :disabled="!!group.disabled"
+      >

Also applies to: 20-21, 34-35, 48-49

examples/sites/demos/mobile-first/app/select-wrapper/remote-method.vue (1)

49-61: Optional: expose scene 4 loading state or drop loading4

remoteMethod4 toggles loading4, but scene 4’s <tiny-select> never binds it, so the flag is effectively unused.

If you want consistent UX with the other scenes, you can wire it up:

-    <tiny-select
+    <tiny-select
       v-model="value4"
       multiple
       filterable
       remote
       :remote-config="{ clearData: true, showIcon: true }"
       reserve-keyword
       :remote-method="remoteMethod4"
     >

to:

    <tiny-select
      v-model="value4"
      multiple
      filterable
      remote
      :remote-config="{ clearData: true, showIcon: true }"
      reserve-keyword
      :remote-method="remoteMethod4"
+     :loading="loading4"
+     loading-text="Loading..."
    >

Otherwise, consider removing loading4 and the toggling logic to keep the demo lean.

Also applies to: 118-120, 235-247

examples/sites/demos/mobile-first/app/select-wrapper/multiple-mix.vue (1)

71-83: Optional: remove unused .visible-form styles

.visible-form is defined in the scoped styles but not used in this component. If no other code relies on it, consider removing it to keep the demo CSS minimal.

examples/sites/demos/mobile-first/app/select-wrapper/memoize-usage.vue (1)

40-44: Optional: initialize cacheValue as a string for clearer intent

cacheValue is initialized as an array but later assigned the string from localStorage. Functionally this works, but initializing it as a string (e.g., '') better reflects its eventual type and the way it’s rendered in the <p>.

-      cacheValue: []
+      cacheValue: ''

Also applies to: 47-54

examples/sites/demos/mobile-first/app/select-wrapper/copy-single.vue (1)

9-10: Avoid depending on internal TinySelect state in filter()

filter() reaches into this.$refs.selectRef.state.cachedOptions and toggles item.state.visible directly. This works today but tightly couples the demo to TinySelectWrapper’s internal implementation, which may change.

If the library exposes an official way to implement custom filtering (e.g., via the filter-method contract without touching internal state, or via a documented API on the select instance), prefer that to keep the example future-proof.

Please double-check the latest TinySelectWrapper filter-method documentation to confirm whether manipulating state.cachedOptions is the recommended pattern.

Also applies to: 119-131

examples/sites/demos/mobile-first/app/select-wrapper/slot-default.vue (1)

55-61: Consider using varied subnet data for more realistic demonstration.

All subnet options display identical IP addresses (192.168.0.1/24) and IP counts (可用 IP 数 250). For a more realistic and educational demo, consider varying these values across options.

Apply this diff to improve the demo data:

       options2: [
-        { value: '选项 1', label: '子网 1(192.168.0.1/24)', desc: '可用 IP 数 250' },
-        { value: '选项 2', label: '子网 2(192.168.0.1/24)', desc: '可用 IP 数 250' },
-        { value: '选项 3', label: '子网 3(192.168.0.1/24)', desc: '可用 IP 数 250' },
-        { value: '选项 4', label: '子网 4(192.168.0.1/24)', desc: '可用 IP 数 250' },
-        { value: '选项 5', label: '子网 5(192.168.0.1/24)', desc: '可用 IP 数 250' }
+        { value: '选项 1', label: '子网 1(192.168.1.0/24)', desc: '可用 IP 数 250' },
+        { value: '选项 2', label: '子网 2(192.168.2.0/24)', desc: '可用 IP 数 245' },
+        { value: '选项 3', label: '子网 3(192.168.3.0/24)', desc: '可用 IP 数 230' },
+        { value: '选项 4', label: '子网 4(192.168.4.0/24)', desc: '可用 IP 数 200' },
+        { value: '选项 5', label: '子网 5(192.168.5.0/24)', desc: '可用 IP 数 180' }
       ],
examples/sites/demos/mobile-first/app/select-wrapper/binding-obj.vue (2)

7-9: Improve how the bound object value is displayed

Interpolating {{ value }} will render [object Object], which isn’t very informative in the demo. Consider showing a specific field or a JSON string instead, e.g. {{ value.val }} (id: {{ value.id }}) or {{ JSON.stringify(value, null, 2) }}.


3-5: Prefer a stable key over the array index in v-for

Using :key="index" works but can cause unnecessary re-renders if the list changes. Since each option has a unique object, you can key by a stable field like item.obj.id for better practice:

-  <tiny-option v-for="(item, index) in options" :key="index" :label="item.text" :value="item.obj">
+  <tiny-option v-for="item in options" :key="item.obj.id" :label="item.text" :value="item.obj">
examples/sites/demos/mobile-first/app/select-wrapper/nest-grid-remote.vue (1)

120-127: Remove debug console.log from remoteMethod

console.log(filterData, value) will spam the console whenever remote searches run. For a shipped demo, it’s better to drop this debug log and just resolve the filtered data.

-    remoteMethod(value) {
-      const filterData = this.filter(value)
-      console.log(filterData, value)
+    remoteMethod(value) {
+      const filterData = this.filter(value)
       return new Promise((resolve) => {
         setTimeout(() => {
           resolve(filterData)
         }, 500)
       })
     },
examples/sites/demos/mobile-first/app/select-wrapper/nest-tree.vue (1)

118-147: Lazy-load logic is fine; consider clarifying node data if you want less duplication

treeOpLazy.load always returns the same child list for level-1 nodes and reuses IDs (1, 2) regardless of which parent was expanded. That’s acceptable for a simple example, but if you want the demo to better reflect realistic tree structures, you might vary the children based on node.id and keep IDs unique per node.

examples/sites/demos/mobile-first/app/select-wrapper/nest-grid-init-query.vue (1)

5-20: Duplicate, unused ref="select" on both TinySelect instances

Both TinySelect elements declare ref="select", but the script never uses this.$refs.select. Keeping duplicate, unused refs adds noise and can confuse future readers.

Consider either:

  • Removing the ref attributes entirely, or
  • Keeping a single meaningful ref and actually using it where needed.

Also applies to: 25-40

examples/sites/demos/mobile-first/app/select-wrapper/nest-grid.vue (1)

26-36: Tidy up unused ref and duplicated grid data

  • The third TinySelect has ref="select", but the component never uses this.$refs.select. You can drop the ref to reduce noise, or wire it up if you plan to use it.
  • gridOpSingle.data and gridOpMulti.data are identical. Extracting the shared array into a single constant (or data property) used by both configs would make future edits less error‑prone.

Also applies to: 63-92

examples/sites/demos/mobile-first/app/select-wrapper/allow-create.vue (1)

5-15: Unused dialog-style creation flow and missing selectDom ref

The current template only uses TinySelect + TinyOption to demonstrate allow-create / default-first-option. However, the script still contains:

  • Registered components: TinyInput, TinyButton, TinyDialogBox (never used in the template).
  • Data: boxVisibility, optionLabel, optionValue (unused).
  • Methods: handleAddOption and handleConfirm, which are never bound to any template events.
    • handleConfirm also calls this.$refs.selectDom.focus(), but there is no ref="selectDom" in the template, which would throw if the method were ever invoked.

To keep the demo clear and maintainable, consider one of these approaches:

  • If you want a dialog-based creation flow:
    Wire these methods and fields into the template (add dialog, inputs, buttons, and a ref="selectDom" on the target TinySelect), ensuring the focus call is valid.

  • If you just rely on TinySelect’s built‑in allow-create behavior:
    Remove the unused components, data, and methods (including the selectDom focus call) so the example only contains what it actually uses.

Also applies to: 28-69

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c29f2bd and 3e02397.

📒 Files selected for processing (49)
  • examples/sites/demos/mobile-first/app/select-wrapper/all-text.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/allow-create.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/automatic-dropdown.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/basic-usage.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/binding-obj.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/cache-usage.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/clear-no-match-value.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/clearable.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/collapse-tags.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/copy-multi.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/copy-single.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/disabled.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/events.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/extra-query-params.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/filter-method.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/filter-mode.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/hide-drop.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/init-label.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/is-drop-inherit-width.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/manual-focus-blur.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/map-field.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/memoize-usage.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/multiple-mix.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/multiple.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/native-properties.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/nest-grid-disable.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/nest-grid-init-query.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/nest-grid-remote.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/nest-grid.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/nest-radio-grid-much-data.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/nest-tree.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/no-data-text.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/optimization.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/option-group.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/popup-style-position.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/remote-method.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/show-alloption.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/show-tip.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/size.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/slot-default.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/slot-empty.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/slot-header-footer.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/slot-label.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/slot-prefix.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/slot-reference.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/tag-type.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/webdoc/select-wrapper.cn.md (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/webdoc/select-wrapper.en.md (1 hunks)
  • examples/sites/demos/mobile-first/app/select-wrapper/webdoc/select-wrapper.js (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:

  • examples/sites/demos/mobile-first/app/select-wrapper/show-alloption.vue
  • examples/sites/demos/mobile-first/app/select-wrapper/webdoc/select-wrapper.js
  • examples/sites/demos/mobile-first/app/select-wrapper/native-properties.vue
  • examples/sites/demos/mobile-first/app/select-wrapper/is-drop-inherit-width.vue
  • examples/sites/demos/mobile-first/app/select-wrapper/show-tip.vue
  • examples/sites/demos/mobile-first/app/select-wrapper/collapse-tags.vue
  • examples/sites/demos/mobile-first/app/select-wrapper/slot-prefix.vue
  • examples/sites/demos/mobile-first/app/select-wrapper/hide-drop.vue
  • examples/sites/demos/mobile-first/app/select-wrapper/clear-no-match-value.vue
  • examples/sites/demos/mobile-first/app/select-wrapper/slot-label.vue
  • examples/sites/demos/mobile-first/app/select-wrapper/binding-obj.vue
  • examples/sites/demos/mobile-first/app/select-wrapper/disabled.vue
  • examples/sites/demos/mobile-first/app/select-wrapper/nest-grid-disable.vue
  • examples/sites/demos/mobile-first/app/select-wrapper/cache-usage.vue
  • examples/sites/demos/mobile-first/app/select-wrapper/allow-create.vue
  • examples/sites/demos/mobile-first/app/select-wrapper/slot-default.vue
  • examples/sites/demos/mobile-first/app/select-wrapper/events.vue
  • examples/sites/demos/mobile-first/app/select-wrapper/nest-grid.vue
  • examples/sites/demos/mobile-first/app/select-wrapper/no-data-text.vue
  • examples/sites/demos/mobile-first/app/select-wrapper/memoize-usage.vue
  • examples/sites/demos/mobile-first/app/select-wrapper/popup-style-position.vue
  • examples/sites/demos/mobile-first/app/select-wrapper/tag-type.vue
  • examples/sites/demos/mobile-first/app/select-wrapper/extra-query-params.vue
  • examples/sites/demos/mobile-first/app/select-wrapper/option-group.vue
  • examples/sites/demos/mobile-first/app/select-wrapper/filter-method.vue
  • examples/sites/demos/mobile-first/app/select-wrapper/map-field.vue
  • examples/sites/demos/mobile-first/app/select-wrapper/multiple.vue
  • examples/sites/demos/mobile-first/app/select-wrapper/basic-usage.vue
  • examples/sites/demos/mobile-first/app/select-wrapper/size.vue
  • examples/sites/demos/mobile-first/app/select-wrapper/slot-header-footer.vue
  • examples/sites/demos/mobile-first/app/select-wrapper/filter-mode.vue
  • examples/sites/demos/mobile-first/app/select-wrapper/slot-reference.vue
  • examples/sites/demos/mobile-first/app/select-wrapper/clearable.vue
  • examples/sites/demos/mobile-first/app/select-wrapper/copy-single.vue
🔇 Additional comments (36)
examples/sites/demos/mobile-first/app/select-wrapper/slot-empty.vue (1)

1-25: Empty-slot demo is clear, minimal, and consistent with the other select-wrapper examples

Template, component registration, and v-model state are all straightforward and idiomatic. This is a good focused demo of the empty slot without extra noise.

examples/sites/demos/mobile-first/app/select-wrapper/tag-type.vue (2)

1-29: Template, bindings, and data model look correct

  • v-model="value" with multiple and an array value is consistent, and option value fields match the initial selection values.
  • v-for="item in options" with :key="item.value" is fine for this static options list.
  • Import/registration of TinySelectWrapper as TinySelect and TinyOption is straightforward and consistent with other demos.

32-35: Scoped styling is safe and appropriate for the demo

The .tiny-select scoped width override is minimal, localized, and should not affect other components beyond this demo.

examples/sites/demos/mobile-first/app/select-wrapper/size.vue (1)

24-47: Script uses TinySelectWrapper and multi-select binding correctly

Importing TinySelectWrapper as TinySelect and binding v-model to arrays of option value strings is correct for multiple mode. The initial selections and options structure look consistent and should work as expected in the demo.

examples/sites/demos/mobile-first/app/select-wrapper/init-label.vue (1)

1-34: LGTM!

The component configuration and setup correctly demonstrate the TinySelect wrapper with grid rendering, remote data, and the init-label feature.

examples/sites/demos/mobile-first/app/select-wrapper/collapse-tags.vue (1)

1-22: Template scenarios are clear and correctly wired

Three separate scenes cleanly demonstrate the different collapse behaviors, with v-model, multiple, v-for, and keys all used consistently. No changes needed here.

examples/sites/demos/mobile-first/app/select-wrapper/optimization.vue (1)

1-20: Overall example structure looks clear and idiomatic

Template, v-model usage for single/multi select, shared onChange handler with TinyModal.message, and the scoped styling for .tiny-select and <p> tags all look consistent with a simple docs demo. I don’t see any functional issues here.

Also applies to: 39-59

examples/sites/demos/mobile-first/app/select-wrapper/extra-query-params.vue (1)

1-44: LGTM!

The template correctly demonstrates dependent selects with grid rendering, remote search, and the extra-query-params feature. The prop bindings and event handling are appropriate for this demo.

examples/sites/demos/mobile-first/app/select-wrapper/popup-style-position.vue (2)

1-5: Template configuration is appropriate for the demo.

The placement="top" combined with :popper-append-to-body="false" correctly demonstrates top-positioned dropdown behavior, which aligns with the file's purpose of showcasing popup positioning.


29-40: Styles are well-structured.

The scoped styles appropriately set component dimensions, while the global .drop class correctly uses a CSS variable for theming. The margin-top: 30px provides necessary space for the top-positioned dropdown.

examples/sites/demos/mobile-first/app/select-wrapper/manual-focus-blur.vue (1)

38-79: Overall component structure and focus/blur wiring look good.

Imports, refs, and the focus/blur handlers are straightforward and consistent with other TinySelect demos. Styles are scoped and minimal, with no obvious side effects.

Also applies to: 82-90

examples/sites/demos/mobile-first/app/select-wrapper/filter-method.vue (1)

60-72: Avoid direct manipulation of internal component state.

The custom filter method directly accesses and mutates the component's internal state (customFilterRef.state.cachedOptions and item.state.visible). This violates encapsulation principles and creates tight coupling to TinySelect's implementation details. If the component's internal structure changes, this code will break and sets a poor example for users referencing this demo.

Refactor to use the component's public API, props, or events if available. If internal state access is necessary, document it clearly as an advanced usage pattern with appropriate caveats about maintenance risks.

examples/sites/demos/mobile-first/app/select-wrapper/copy-multi.vue (1)

43-66: Clarify copy functionality implementation in component.

The provided snippet (lines 43-66) shows component setup and data initialization but doesn't include the template or full event handler logic. Verify whether the copyable prop on TinySelect handles clipboard operations automatically, or if additional @copy event handlers or methods are needed to demonstrate the copy-to-clipboard feature and populate the copyValue variable.

examples/sites/demos/mobile-first/app/select-wrapper/option-group.vue (2)

1-58: Overall demo structure and usage of TinySelectWrapper look consistent

Template structure, component registration (TinySelectWrapper as TinySelect, TinyOption, TinyOptionGroup), grouped options data, and the scoped width style all match the patterns used in other Tiny Vue demos and clearly illustrate the four scenarios.

Also applies to: 60-68, 73-95, 101-105


5-7: Fix v-model data types for single vs. multiple select scenarios

value1 and value2 are initialized with types opposite to how they're used:

  • value1 is an array but bound to a single-select (Line 19).
  • value2 is a string but bound to multiple selects (Lines 5, 33, 47).

Standard Vue select patterns expect multiple mode to use array v-model and single-select to use scalar v-model. Aligning the initializations will ensure correct behavior:

-      value1: [],
-      value2: '',
+      value1: '',
+      value2: [],

Verify this matches TinySelectWrapper's v-model type requirements.

examples/sites/demos/mobile-first/app/select-wrapper/disabled.vue (3)

95-95: Verify that pre-selecting a disabled option is intentional.

Scene 2's value2 is initialized with ['选项 2'], which is disabled in options2. While Scene 4 explicitly demonstrates pre-selected disabled items, Scene 2's purpose ("多选 + 下拉某项禁用") suggests it may be demonstrating selectable options with some disabled, not pre-selection of disabled items.

Confirm whether Scene 2 should start with an empty selection or if pre-selecting the disabled option is intentional to demonstrate locked-selection behavior.


1-108: Well-structured demo component.

The file demonstrates good practices:

  • Clear scene labeling with Chinese descriptions for user understanding
  • Proper component registration and imports
  • Correct v-for with :key bindings for list rendering
  • Scoped styles to prevent CSS conflicts
  • Comprehensive coverage of disabled state scenarios

The demo effectively showcases various disabled configurations for documentation purposes.


6-6: Verify the autocomplete prop usage in TinySelect.

The autocomplete attribute on line 6 is used as a boolean prop without an explicit value. Confirm whether TinySelect's autocomplete prop accepts:

  • Boolean values (current usage is correct)
  • Or specific string values like "on"/"off"

Check the TinySelect component API documentation or prop definitions to determine the correct usage and expected behavior when combined with disabled.

examples/sites/demos/mobile-first/app/select-wrapper/is-drop-inherit-width.vue (1)

1-51: LGTM!

The component correctly demonstrates the dropdown width behavior in two scenarios: default width (content-driven) and inherited width from the input. The intentionally long label on line 30 effectively showcases the difference.

examples/sites/demos/mobile-first/app/select-wrapper/filter-mode.vue (1)

1-46: LGTM!

The component correctly demonstrates both default and transparent filter modes using the blank attribute. The implementation is clear and follows the established pattern.

examples/sites/demos/mobile-first/app/select-wrapper/clear-no-match-value.vue (1)

1-54: LGTM!

The component appropriately demonstrates the clear-no-match-value feature by intentionally initializing values that don't match any options. This effectively showcases how the component handles such scenarios.

examples/sites/demos/mobile-first/app/select-wrapper/map-field.vue (1)

1-68: LGTM!

The component effectively demonstrates custom field mapping in both standard options and grid render modes. The use of value-field and text-field props is correctly implemented.

examples/sites/demos/mobile-first/app/select-wrapper/events.vue (1)

1-112: LGTM!

The component comprehensively demonstrates event handling for both single and multi-select scenarios. All event handlers are properly implemented and use consistent patterns with informative feedback.

examples/sites/demos/mobile-first/app/select-wrapper/slot-reference.vue (1)

2-7: LGTM: reference-slot demo is clear and consistent

Usage of TinySelectWrapper with a custom #reference slot and TinyIconSetting is straightforward and correctly wired to the options data and v-model. No changes needed.

Also applies to: 14-31

examples/sites/demos/mobile-first/app/select-wrapper/clearable.vue (1)

2-4: LGTM: clearable single-select demo behaves as expected

clearable is correctly applied, default selection is valid, and the scoped width styling keeps the control consistent across the mobile-first examples.

Also applies to: 15-26

examples/sites/demos/mobile-first/app/select-wrapper/hide-drop.vue (1)

2-4: LGTM: hide-drop example is wired correctly

:hide-drop="true" is correctly passed to TinySelectWrapper, and the options/v-model setup matches the rest of the demo suite.

Also applies to: 15-26

examples/sites/demos/mobile-first/app/select-wrapper/webdoc/select-wrapper.en.md (1)

1-7: LGTM!

The documentation structure appears intentional, with detailed examples and API documentation defined in the companion select-wrapper.js configuration file.

examples/sites/demos/mobile-first/app/select-wrapper/webdoc/select-wrapper.cn.md (1)

1-7: LGTM!

The Chinese documentation follows the same pattern as the English version, with detailed examples and API documentation defined in the companion select-wrapper.js configuration file.

examples/sites/demos/mobile-first/app/select-wrapper/automatic-dropdown.vue (1)

1-62: LGTM!

The component correctly demonstrates focus behavior with and without automatic-dropdown, using appropriate data types and ref-based focus control.

examples/sites/demos/mobile-first/app/select-wrapper/all-text.vue (1)

1-43: LGTM!

The component correctly demonstrates the all-text and show-all-text-tag features with proper array initialization for multi-select mode.

examples/sites/demos/mobile-first/app/select-wrapper/webdoc/select-wrapper.js (1)

60-76: Verify that all referenced demo files exist.

The configuration references demo files that need verification: multiple-mix.vue (line 75), and other references around lines 666 and 692. Ensure these files either exist in the repository or are included in this PR.

examples/sites/demos/mobile-first/app/select-wrapper/basic-usage.vue (1)

1-47: Basic example is clear and consistent

Template, data, and icon usage all look correct and align with other TinySelectWrapper demos; no issues spotted.

examples/sites/demos/mobile-first/app/select-wrapper/no-data-text.vue (1)

1-48: Empty-state scenarios are implemented correctly

The three configurations (default, custom no-data-text, and show-empty-image) are wired up properly and clearly demonstrate the different empty states.

examples/sites/demos/mobile-first/app/select-wrapper/multiple.vue (1)

1-133: Comprehensive multiple-select demo looks solid

The various multi-select scenarios are consistently wired (options, v-models, required/disabled flags, limit, and display props) and appear correct for showcasing TinySelectWrapper behavior.

examples/sites/demos/mobile-first/app/select-wrapper/nest-grid-disable.vue (1)

1-122: Grid disable scenarios are correctly wired

The selectConfig/radioConfig checkMethod usage and gridOp/gridOpRadio configurations look coherent for demonstrating disabled rows in both single and multiple selection modes.

examples/sites/demos/mobile-first/app/select-wrapper/nest-radio-grid-much-data.vue (1)

1-50: Large-data grid configuration is correct

The mounted() loop correctly builds 801 rows with the expected fields and assigns them to gridOpRadio.data; the grid/radio configuration aligns with the template usage.

Comment on lines +34 to +36
cacheChange() {
this.cacheValue = window.localStorage.getItem(`tiny_memorize_${this.cacheOp.key}`)
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add error handling for localStorage access.

Direct localStorage access can throw exceptions in private browsing mode or when storage is disabled. Since this is a demo that users may copy, it's important to demonstrate safe usage patterns.

Apply this diff to add error handling:

 cacheChange() {
-  this.cacheValue = window.localStorage.getItem(`tiny_memorize_${this.cacheOp.key}`)
+  try {
+    this.cacheValue = window.localStorage.getItem(`tiny_memorize_${this.cacheOp.key}`) || ''
+  } catch (e) {
+    console.warn('localStorage access failed:', e)
+    this.cacheValue = ''
+  }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
cacheChange() {
this.cacheValue = window.localStorage.getItem(`tiny_memorize_${this.cacheOp.key}`)
}
cacheChange() {
try {
this.cacheValue = window.localStorage.getItem(`tiny_memorize_${this.cacheOp.key}`) || ''
} catch (e) {
console.warn('localStorage access failed:', e)
this.cacheValue = ''
}
}
🤖 Prompt for AI Agents
In examples/sites/demos/mobile-first/app/select-wrapper/cache-usage.vue around
lines 34 to 36, the direct call to window.localStorage.getItem may throw (e.g.
in private browsing or when storage is disabled); wrap the access in a try/catch
(and optionally check typeof window !== 'undefined' && window.localStorage) so
exceptions are caught, set this.cacheValue to null or a safe fallback when an
error occurs, and log or silently ignore the error as appropriate for a demo so
the component won’t crash.

<br />
<p>场景 2:多选一键复制所有标签</p>
<br />
<tiny-select ref="selectCopyable" v-model="value2" multiple copyable>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix duplicate ref attributes.

Three different <tiny-select> instances use the same ref name "selectCopyable". In Vue, refs must be unique; only the last instance will be accessible via this.$refs.selectCopyable, breaking any attempts to access the first two programmatically.

Apply this diff to assign unique ref names:

-    <tiny-select ref="selectCopyable" v-model="value2" multiple copyable>
+    <tiny-select ref="selectCopyable1" v-model="value2" multiple copyable>
-    <tiny-select ref="selectCopyable" v-model="value2" multiple copyable text-split="/">
+    <tiny-select ref="selectCopyable2" v-model="value2" multiple copyable text-split="/">
     <tiny-select
-      ref="selectCopyable"
+      ref="selectCopyable3"
       v-model="value2"

Also applies to: 19-19, 25-25

🤖 Prompt for AI Agents
In examples/sites/demos/mobile-first/app/select-wrapper/copy-multi.vue around
lines 12, 19 and 25, three <tiny-select> elements share the same ref
"selectCopyable", which must be unique; rename each ref to unique identifiers
(e.g., "selectCopyable1", "selectCopyable2", "selectCopyable3") in those lines
and update any code that accesses this.$refs.selectCopyable to use the new ref
names (or iterate over them) so each component can be referenced individually.

Comment on lines +24 to +34
<tiny-select
ref="selectCopyable"
v-model="value2"
multiple
copyable
text-split="/"
:multiple-limit="2"
show-limit-text
>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-select>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add a descriptive label for the fourth scenario.

Scenarios 1, 2, and 3 include descriptive paragraph labels, but this fourth configuration (with multiple-limit and show-limit-text) lacks one. Adding a label improves the demo's educational value.

Apply this diff to add a label:

     <br />
+    <p>场景 4:多选限制数量并显示复制</p>
+    <br />
     <tiny-select
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<tiny-select
ref="selectCopyable"
v-model="value2"
multiple
copyable
text-split="/"
:multiple-limit="2"
show-limit-text
>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-select>
<br />
<p>场景 4:多选限制数量并显示复制</p>
<br />
<tiny-select
ref="selectCopyable"
v-model="value2"
multiple
copyable
text-split="/"
:multiple-limit="2"
show-limit-text
>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-select>
🤖 Prompt for AI Agents
In examples/sites/demos/mobile-first/app/select-wrapper/copy-multi.vue around
lines 24 to 34, the fourth demo instance of tiny-select is missing a descriptive
paragraph label; add a short descriptive label immediately above the tiny-select
explaining this configuration (for example: "Scenario 4: copyable with
multiple-limit and show-limit-text" or similar), matching the style of the
previous scenario labels so the demo remains consistent and educational.

multiple
disabled
hover-expand
disabled-tooltip-content="我是自定义内容"
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# Search for Select component definition files
fd -e ts -e js -e vue "select" | grep -v node_modules | grep -v dist | head -30

Repository: opentiny/tiny-vue

Length of output: 178


🏁 Script executed:

# Search for disabled-tooltip-content prop definition
rg "disabled-tooltip-content" --type vue --type ts --type js

Repository: opentiny/tiny-vue

Length of output: 178


🏁 Script executed:

# Look for Select component props definition
rg "props" -A 20 --type ts --type js | grep -i "disabled-tooltip" -B 5 -A 5

Repository: opentiny/tiny-vue

Length of output: 178


🌐 Web query:

TinyVue Select disabledTooltipContent prop documentation

💡 Result:

I can find that for you — do you want me to search the TinyVue (OpenTiny) docs and repo now and return the exact documentation and examples for the Select component's disabledTooltipContent prop?


🌐 Web query:

TinyVue tiny-select component props API reference

💡 Result:

Do you mean the Select (tiny-select) component from the OpenTiny / TinyVue library? Which TinyVue version (v2 or v3) do you need the props for — or do you want the full props table and examples? I can fetch the exact API list from the official docs/GitHub once you confirm.

References: OpenTiny TinyVue repo and docs home. [1][2]

[1] https://github.com/opentiny/tiny-vue
[2] https://opentiny.design/


🌐 Web query:

site:github.com opentiny/tiny-vue Select disabledTooltipContent

💡 Result:

I couldn't find any occurrences of "disabledTooltipContent" in the opentiny/tiny-vue repository. The repository and its Select/tooltip-related changelog entries are available here for reference: [1] opentiny/tiny-vue (repo) and [2] releases/changelog (mentions select/tooltip fixes).

Sources:
[1] https://github.com/opentiny/tiny-vue
[2] https://github.com/opentiny/tiny-vue/releases


🌐 Web query:

site:opentiny.design select component props disabled tooltip

💡 Result:

I couldn't find any docs at opentiny.design (no results). I did find OpenTiny docs at a different host and general guidance from other UI libraries:

  • OpenTiny React docs (available at opentiny.mild.blue) list component props but don't show a built-in Select-tooltip-on-disabled pattern. [1]
  • Many tooltip implementations disable showing for disabled native controls; common workaround is to wrap the disabled control in a non-disabled element (e.g., a span) and attach the tooltip to that wrapper so hover/focus events still fire. This pattern is documented in several design-system notes. [2][3]

Recommendation: if your Select is a native/disabled control, wrap it in a wrapper element (span/div) and attach the Tooltip to that wrapper so the tooltip can display while the Select remains disabled.

Sources:
[1] OpenTiny React reference.
[2] CORE Design System — Tooltip (notes about disabled inputs).
[3] Carbon issue discussing tooltips on disabled buttons and the wrapper workaround.


Remove or replace the undocumented disabled-tooltip-content prop.

The disabled-tooltip-content prop does not appear to be part of the TinySelect component's public API. This prop was not found in the opentiny/tiny-vue repository or documentation. Either remove this attribute or replace it with the correct prop name if tooltip content customization for disabled state is intended.

🤖 Prompt for AI Agents
In examples/sites/demos/mobile-first/app/select-wrapper/disabled.vue around line
61, the attribute disabled-tooltip-content is undocumented for the TinySelect
component; remove this attribute or replace it with the correct documented prop
for customizing tooltip content (consult the component API for the proper prop
name, e.g., tooltip-content or an appropriate slot) and ensure any tooltip
behavior is implemented via supported props or slots so the example matches the
public API.

Comment on lines +142 to +148
change(radioValue1) {
this.extraQueryParams = radioValue1
this.radioValue2 = this.radioValue2.filter((value2) => {
const selected = this.children.find((child) => child.id === value2)
return radioValue1.includes(selected.parent)
})
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Potential TypeError if child is not found.

If this.children.find() returns undefined (e.g., stale data or edge case where value2 doesn't match any child), accessing selected.parent will throw a TypeError.

Apply this diff to add a defensive check:

     change(radioValue1) {
       this.extraQueryParams = radioValue1
       this.radioValue2 = this.radioValue2.filter((value2) => {
         const selected = this.children.find((child) => child.id === value2)
-        return radioValue1.includes(selected.parent)
+        return selected && radioValue1.includes(selected.parent)
       })
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
change(radioValue1) {
this.extraQueryParams = radioValue1
this.radioValue2 = this.radioValue2.filter((value2) => {
const selected = this.children.find((child) => child.id === value2)
return radioValue1.includes(selected.parent)
})
}
change(radioValue1) {
this.extraQueryParams = radioValue1
this.radioValue2 = this.radioValue2.filter((value2) => {
const selected = this.children.find((child) => child.id === value2)
return selected && radioValue1.includes(selected.parent)
})
}
🤖 Prompt for AI Agents
In examples/sites/demos/mobile-first/app/select-wrapper/extra-query-params.vue
around lines 142 to 148, the filter callback uses this.children.find(...) and
immediately accesses selected.parent which can throw if find returns undefined;
modify the filter to first check that selected is truthy and only include the
item when selected exists and radioValue1.includes(selected.parent) (i.e.,
return !!selected && radioValue1.includes(selected.parent)) so missing children
are skipped safely.

@@ -0,0 +1,34 @@
<template>
<tiny-select v-model="value" multiple :show-alloption="false">
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix type mismatch between multiple select and v-model initialization.

The select uses multiple mode but value is initialized as an empty string. For multi-select, the v-model should be bound to an array.

Apply this diff to fix the initialization:

-      value: ''
+      value: []

Also applies to: 24-24

🤖 Prompt for AI Agents
In examples/sites/demos/mobile-first/app/select-wrapper/show-alloption.vue
around lines 2 and 24, the tiny-select is rendered with the multiple prop while
the bound v-model variable `value` is initialized as an empty string; change the
initial value to an empty array so the v-model matches multi-select semantics
(initialize value as [] instead of "") and ensure any other usages in the same
file that assume a string handle an array consistently.

@@ -0,0 +1,28 @@
<template>
<tiny-select v-model="value" multiple show-overflow-tooltip style="width: 200px">
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix type mismatch between multiple select and v-model initialization.

The select uses multiple mode but value is initialized as an empty string. For multi-select, the v-model should be bound to an array.

Apply this diff to fix the initialization:

       value: ''
+      value: []

Also applies to: 24-24

🤖 Prompt for AI Agents
In examples/sites/demos/mobile-first/app/select-wrapper/show-tip.vue around
lines 2 and 24, the tiny-select is used with the multiple attribute but the
v-model value is initialized as an empty string; change the v-model initial
value to an array (e.g., []) and update any TypeScript/prop typings if present
to reflect an array type so the multi-select binds to an array rather than a
string.

}
.select-footer {
text-align: center;
background-color: rgb(207, 243, 232, 0.3);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix invalid CSS syntax for rgba color.

The rgb() function only accepts three values (red, green, blue). To include an alpha channel, use rgba().

Apply this diff:

 .select-footer {
   text-align: center;
-  background-color: rgb(207, 243, 232, 0.3);
+  background-color: rgba(207, 243, 232, 0.3);
   padding: 8px;
 }
 .select-header {
   text-align: center;
-  background-color: rgb(207, 243, 232, 0.3);
+  background-color: rgba(207, 243, 232, 0.3);
   padding: 8px;
 }

Also applies to: 52-52

🤖 Prompt for AI Agents
In examples/sites/demos/mobile-first/app/select-wrapper/slot-header-footer.vue
around lines 47 and 52, the CSS uses invalid syntax "rgb(207, 243, 232, 0.3)"
which mixes an alpha value into rgb(); change these declarations to use
rgba(207, 243, 232, 0.3) (or use a CSS color function that supports alpha like
rgba() or hsla()) so the background-color values are valid and include the
intended transparency.

Comment on lines +72 to +85
<style lang="less" scoped>
.tiny-select {
width: 280px;
}

.demo-select-slot-label.label-user-head,
.tiny-tooltip .label-user-head {
display: inline-block;
height: 18px;
width: 18px;
margin-right: 4px;
vertical-align: middle;
}
</style>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fix selector so label avatars in the main demo are actually styled

The selector:

.demo-select-slot-label.label-user-head,
.tiny-tooltip .label-user-head {
  ...
}

targets elements that have both demo-select-slot-label and label-user-head simultaneously, but in the template those classes are on different elements (wrapper div vs. img). As a result, the first selector never matches and the avatar images in the main select aren’t styled.

Use a descendant selector instead:

-.demo-select-slot-label.label-user-head,
+.demo-select-slot-label .label-user-head,
 .tiny-tooltip .label-user-head {
   display: inline-block;
   height: 18px;
   width: 18px;
   margin-right: 4px;
   vertical-align: middle;
 }
🤖 Prompt for AI Agents
In examples/sites/demos/mobile-first/app/select-wrapper/slot-label.vue around
lines 72 to 85, the first selector currently requires both classes on the same
element (.demo-select-slot-label.label-user-head) but in the template the
wrapper has .demo-select-slot-label and the img has .label-user-head, so the
rule never applies; change the selector to use a descendant selector (e.g.,
.demo-select-slot-label .label-user-head) so the avatar img inside the wrapper
is matched, leaving the .tiny-tooltip .label-user-head selector as-is.

{ value: '选项 4', label: '重庆' },
{ value: '选项 5', label: '深圳' }
],
value: ''
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Initialize value as an array for multi-select.

The TinySelect on line 2 has the multiple attribute, which requires the v-model binding to be an array. Initializing value as an empty string will cause errors when the component attempts to manage multiple selections.

Apply this diff:

-      value: ''
+      value: []
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
value: ''
value: []
🤖 Prompt for AI Agents
In examples/sites/demos/mobile-first/app/select-wrapper/slot-prefix.vue around
line 29, the property `value` is initialized as an empty string but the
TinySelect has the `multiple` attribute so v-model must be an array; change the
initialization from an empty string to an empty array ([]) so the component can
manage multiple selections correctly and avoid runtime errors.

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.

1 participant