Skip to content

Conversation

@discreted66
Copy link
Collaborator

@discreted66 discreted66 commented Dec 4, 2025

PR

feat:多端base-select以及grid-select文档

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

    • Extensive mobile-first demos for BaseSelect and GridSelect covering single/multi-select, filtering, remote search, caching, copy/copy-all, tags, slots, tree/grid panels, and big-data/optimization scenarios.
    • GridSelect demos now support both PC and mobile-first modes; many GridSelect examples include remote and parent-child queries.
  • Documentation

    • Added English and Chinese docs and demo metadata for BaseSelect and GridSelect.
  • Chores

    • Updated demo menu to include BaseSelect and GridSelect.

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

coderabbitai bot commented Dec 4, 2025

Walkthrough

Adds mobile-first demo support for BaseSelect and GridSelect: ~40 new Vue demo components, documentation and webdoc config files, menu registration, and an API mode update for grid-select; also tweaks a route helper to handle 'grid-select' paths and adds multi-select scenes to PC grid-select demos.

Changes

Cohort / File(s) Summary
Route helper
examples/docs/newsrc/utils/componentsDoc.js
Added explicit case: when path === 'grid-select' return 'grid-select'; preserves existing grid-* and chart-* prefix handling and default path return.
Grid-Select API
examples/sites/demos/apis/grid-select.js
Top-level mode and prop-level mode values updated from ['pc'] to ['pc','mobile-first'] for multiple props (clearable, filterable, filter-method, grid-op, multiple, radio-config, remote, remote-method, reserve-keyword, select-config, text-field, value-field, etc.).
Mobile-first BaseSelect demos
examples/sites/demos/mobile-first/app/base-select/*
Added many new demo SFCs (e.g., all-text.vue, allow-create.vue, automatic-dropdown.vue, basic-usage.vue, binding-obj.vue, cache-usage.vue, clear-no-match-value.vue, clearable.vue, collapse-tags.vue, copy-multi.vue, copy-single.vue, disabled.vue, events.vue, filter-method.vue, filter-mode.vue, hide-drop.vue, is-drop-inherit-width.vue, manual-focus-blur.vue, map-field.vue, memoize-usage.vue, multiple-mix.vue, multiple.vue, native-properties.vue, no-data-text.vue, optimization.vue, option-group.vue, popup-style-position.vue, remote-method.vue, show-alloption.vue, show-tip.vue, size.vue, slot-default.vue, slot-empty.vue, slot-footer.vue, slot-label.vue, slot-panel.vue, slot-prefix.vue, slot-reference.vue, tag-type.vue). Each is a new Vue component demo registering/using TinyBaseSelect and related subcomponents.
BaseSelect webdocs/config
examples/sites/demos/mobile-first/app/base-select/webdoc/*
Added base-select.cn.md, base-select.en.md, and base-select.js (demo and feature metadata).
Mobile-first GridSelect demos
examples/sites/demos/mobile-first/app/grid-select/*
Added demo SFCs: basic-usage.vue, config.vue, extra-query-params.vue, init-query.vue, radio-bigdata.vue, remote.vue and related webdoc files.
GridSelect webdocs/config
examples/sites/demos/mobile-first/app/grid-select/webdoc/*
Added grid-select.cn.md, grid-select.en.md, and grid-select.js (demo and feature metadata).
Mobile-first menus
examples/sites/demos/mobile-first/menus.js
Registered two new form components in mobile-first menu: BaseSelect (key: 'base-select') and GridSelect (key: 'grid-select', meta.experimental: '3.27.0').
PC GridSelect demos (multi-select additions)
examples/sites/demos/pc/app/grid-select/basic-usage.vue, .../basic-usage-composition-api.vue
Added second scene for multi-select: introduced value2 and gridOpMulti (data + columns) to support multi-select grid demo.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Areas requiring attention:

  • Confirm grid-select API mode changes are intentional and complete for all relevant props.
  • Validate components in many new mobile-first demo SFCs correctly import/register Tiny* components and have consistent prop usage.
  • Review the new getPath special case for unintended interactions with existing prefix logic.
  • Inspect radio-bigdata.vue (800 rows + global window variable) for demo performance or global side-effect concerns.
  • Check webdoc config files (*.js) reference the correct codeFiles paths.

Possibly related PRs

Suggested reviewers

  • zzcr

Poem

🐰 I hopped through demos, one by one,
BaseSelect and GridSelect — mobile fun!
Docs and menus planted neat and spry,
New scenes to view beneath the sky,
A tiny rabbit cheers — demos multiply! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Title check ⚠️ Warning The pull request title contains a typo ('moobile-first' instead of 'mobile-first') and is misleading about the scope—it suggests only documentation changes, but the changeset includes numerous new Vue demo components, configuration files, and utility modifications beyond documentation. Correct the typo to 'mobile-first' and revise the title to accurately reflect the substantial additions of demo components and configurations, e.g., 'feat: add mobile-first base-select and grid-select demos with documentation'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
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: 6

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

Caution

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

⚠️ Outside diff range comments (1)
examples/sites/demos/apis/grid-select.js (1)

53-63: Missing mobile-first mode for modelValue / v-model prop.

The modelValue / v-model prop still has mode: ['pc'] while all other props have been updated to ['pc', 'mobile-first']. This appears to be an oversight since the binding value is essential for mobile-first usage.

         desc: {
           'zh-CN': '绑定值',
           'en-US': 'Bind value'
         },
-        mode: ['pc'],
+        mode: ['pc', 'mobile-first'],
         pcDemo: 'basic-usage'
       },
🟡 Minor comments (16)
examples/sites/demos/mobile-first/app/base-select/tag-type.vue-1-5 (1)

1-5: Add data-tag so the scoped width style applies to this demo

The scoped Less targets [data-tag='tiny-base-select'], but the template never sets this attribute, so the 280px width likely won’t be applied to the rendered select in this demo.

Consider updating the template as follows:

-  <tiny-base-select v-model="value" multiple tag-type="success">
+  <tiny-base-select v-model="value" multiple tag-type="success" data-tag="tiny-base-select">

Also applies to: 32-35

examples/sites/demos/mobile-first/app/base-select/events.vue-21-33 (1)

21-33: Add missing @clear event handler for consistency.

The multi-select instance has the clearable prop but is missing the @clear event handler that the single-select instance includes. For a complete events demo, both instances should demonstrate the same events where applicable.

Apply this diff to add the missing handler:

     <tiny-base-select
       v-model="value2"
       multiple
       clearable
       @change="change"
       @blur="blur"
       @focus="focus"
       @visible-change="visibleChange"
+      @clear="clear"
       @remove-tag="removeTag"
       @dropdown-click="dropdownClick"
     >
examples/sites/demos/mobile-first/app/base-select/slot-empty.vue-1-10 (1)

1-10: Add click handler to the reload button or clarify it's a placeholder.

The reload button on line 6 appears interactive but has no @click handler, which could mislead developers copying this demo code.

Consider one of these approaches:

Option 1: Add a functional reload handler

     <template #empty>
       <div class="custom-empty">
         <p>APIG 网关异常</p>
-        <tiny-button size="small">重新加载</tiny-button>
+        <tiny-button size="small" @click="handleReload">重新加载</tiny-button>
       </div>
     </template>

Then add the method in the script section:

   data() {
     return {
       value: ''
     }
+  },
+  methods: {
+    handleReload() {
+      // Reload logic here
+      console.log('Reloading...')
+    }
   }

Option 2: Add a comment explaining it's a placeholder

       <div class="custom-empty">
         <p>APIG 网关异常</p>
+        <!-- 此按钮为示例,实际使用时需添加点击事件处理 -->
         <tiny-button size="small">重新加载</tiny-button>
       </div>
examples/sites/demos/mobile-first/app/base-select/slot-default.vue-5-5 (1)

5-5: Unused popper-class with no corresponding styles.

The popper-class="slot-default" is specified but no CSS rules for .slot-default are defined in either style block. In contrast, Scene 2 defines .double-row styles. If external styling is intended, consider adding a comment; otherwise, define the missing styles or remove the unused class.

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

3-13: Clarify the v-show logic for default filtering.

The v-show="!item.filter" directive references a property that doesn't exist in the options data structure. Since item.filter is undefined, this will always evaluate to true, making the directive ineffective. When using the default filtering mode (filterable without a custom filter-method), the component should handle option visibility internally, so this v-show may be unnecessary.

Consider removing the v-show directive for scenario 1:

     <tiny-option
       v-for="item in options"
-      v-show="!item.filter"
       :key="item.value"
       :label="item.label"
       :value="item.value"
     >
examples/sites/demos/mobile-first/app/base-select/multiple.vue-44-44 (1)

44-44: Fix shared state between scenarios 4 and 5.

Both scenario 4 (line 35) and scenario 5 (line 44) bind to value4, causing them to share selection state. This makes the demos interdependent and potentially confusing for users trying to understand each feature independently.

Apply this diff to use separate state for scenario 5:

     <tiny-base-select
-      v-model="value4"
+      v-model="value5"
       multiple
       :dropdown-icon="iconPopup"
       :drop-style="{ width: '200px', 'min-width': '200px' }"

And add value5 to the data:

       value3: ['选项 1', '选项 2'],
       value4: [],
+      value5: [],
       iconPopup: iconPopup()

Also applies to: 87-87

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

52-54: Initialize options2 to include the default value.

value2 is set to 'Alabama' but options2 starts empty. This mismatch may cause console warnings or display issues until remoteMethod populates the options.

Apply this diff to initialize with the default option:

-      options2: [],
+      options2: [{ value: 'Alabama', label: 'Alabama' }],
examples/sites/demos/mobile-first/app/base-select/remote-method.vue-49-61 (1)

49-61: Loading state wiring is inconsistent across scenarios 4 and 6

  • Line 236–243: remoteMethod4 toggles loading4, but the scenario 4 <tiny-base-select> (Lines 51–59) never binds :loading or loading-text, so the user never sees the loading state.
  • Data defines loading1loading5 (Lines 116–120) but no loading6.
  • Line 96: Scenario 6 binds :loading="loading5", even though remoteMethod6 (Lines 261–271) never toggles loading5 (or any loading flag), so that binding is effectively dead and confusing.
  • loading4 and loading5 end up used in methods that don't match their template bindings.

To make the examples consistent and less confusing, consider one of these options:

  • Option A (wire all loadings):
    • Add loading6 to data(), bind scenario 4 and 6 selects to their own flags, and toggle those flags in remoteMethod4/remoteMethod6.
  • Option B (simplify):
    • If you don't want loading indicators for scenarios 4 and 6, remove the loading4 toggling in remoteMethod4 and the :loading="loading5" binding from scenario 6.

Either way, aligning loading flags with the scenarios they belong to will make the docs easier to follow.

Also applies to: 64-78, 80-101, 116-121, 235-271

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

38-43: Initialize cacheValue as a string to match localStorage usage

cacheValue is initialized as an array but later assigned the result of localStorage.getItem, which is a string or null. This type mismatch is harmless in JS but can be confusing and inconsistent with how the value is displayed.

A small cleanup:

  data() {
    return {
      options,
      value: '选项 3',
-      cacheValue: []
+      cacheValue: ''
    }
  },
examples/sites/demos/mobile-first/app/base-select/show-tip.vue-2-2 (1)

2-2: Conflicting width declarations.

The inline style="width: 200px" on line 2 conflicts with the scoped style width: 280px on line 32. The inline style will take precedence, making the scoped style rule ineffective. For consistency with other demos (e.g., clearable.vue), consider removing the inline style and relying solely on the scoped style.

Apply this diff to remove the inline style:

-  <tiny-base-select v-model="value" multiple show-overflow-tooltip style="width: 200px">
+  <tiny-base-select v-model="value" multiple show-overflow-tooltip>
examples/sites/demos/mobile-first/app/base-select/webdoc/base-select.js-577-588 (1)

577-588: Fix features.filterable.demos to reference the actual demo id

The filterable feature currently points to a demo id that does not exist here:

demos: ['filterable']

But the corresponding demo in this file is defined with demoId: 'filter-method' (Lines 127–139). To keep the feature list functional, this should reference the existing id:

-      demos: ['filterable']
+      demos: ['filter-method']
examples/sites/demos/mobile-first/app/base-select/webdoc/base-select.js-397-405 (1)

397-405: Correct malformed HTML in memoize-usage EN description

The EN paragraph ends with <p> instead of </p>, which can break rendering:

-        'en-US': '<p>If using the tiny-option component, you need to manually add caching functionality.<p>'
+        'en-US': '<p>If using the tiny-option component, you need to manually add caching functionality.</p>'
examples/sites/demos/mobile-first/app/base-select/webdoc/base-select.js-196-205 (1)

196-205: Fix prop name typo in show-alloption EN description

The EN description uses <code>show-allocation</code> but the actual prop is show-alloption. This can confuse users and break search.

Recommend:

-          '<p>By setting the <code>show-allocation</code> attribute, do not display the <code>select all</code> option when multiple selections are made, and display by default.</p>\n'
+          '<p>By setting the <code>show-alloption</code> attribute, the <code>Select all</code> option is hidden in multiple selection mode. It is shown by default.</p>\n'
examples/sites/demos/mobile-first/app/base-select/webdoc/base-select.js-28-41 (1)

28-41: Clarify multiple-limit vs show-limit-text semantics and fix EN wording

The CN/EN descriptions for multiple-limit and show-limit-text in the “multiple” demo currently describe both props as if they limit the maximum number of selectable items, and the EN text says “number of users”. That’s misleading.

Consider tightening this section, for example:

-            通过 <code>multiple-limit</code> 属性限制最多可选择的个数,默认为 0 不限制。<br>
-            通过 <code>show-limit-text</code> 属性限制最多可选择的个数,默认为 0 不限制。<br>
+            通过 <code>multiple-limit</code> 属性限制最多可选择的个数,默认为 0 不限制。<br>
+            通过 <code>show-limit-text</code> 属性控制是否在标签上显示“+N”等超出提示文本。<br>
-            The <code>multiple-limit</code> attribute is used to limit the maximum number of users that can be selected. The default value is 0.
-            The <code>show-limit-text</code> attribute is used to limit the maximum number of users that can be selected. The default value is 0, which is not limited.<br>
+            The <code>multiple-limit</code> attribute limits the maximum number of items that can be selected. The default value 0 means no limit.
+            The <code>show-limit-text</code> attribute controls whether overflow text such as “+N” is displayed when there are many selected items.<br>
examples/sites/demos/mobile-first/app/base-select/slot-prefix.vue-2-2 (1)

2-2: Value type mismatch for multiple select.

The component uses multiple mode but initializes value as an empty string. For multi-select, value should be an array.

       ],
-      value: ''
+      value: []
     }

Also applies to: 29-29

examples/sites/demos/mobile-first/app/base-select/slot-label.vue-77-78 (1)

77-78: CSS selector missing descendant combinator.

The selector .demo-select-slot-label.label-user-head selects elements with both classes on the same element. Since .label-user-head is a child element inside .demo-select-slot-label, you likely need a descendant selector with a space.

-.demo-select-slot-label.label-user-head,
+.demo-select-slot-label .label-user-head,
🧹 Nitpick comments (37)
examples/sites/demos/mobile-first/app/base-select/size.vue (1)

3-10: Consider minor UX polish for labels and mobile responsiveness

Labels mix English (medium / small / mini) and Chinese (默认); consider unifying language to match surrounding docs. Also, for a mobile-first demo, you might prefer a fluid width (e.g. width: 100%; max-width: 280px;) instead of a hard 280px to better adapt on small screens.

Also applies to: 39-48

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

33-41: Consider using responsive width for mobile‑first demo

Since this is under mobile-first demos, a fixed width: 280px may be less adaptive across devices. Consider using a more responsive width (e.g., width: 100% within a constrained container) so the select better fits varying mobile screen sizes.

examples/sites/demos/mobile-first/app/base-select/filter-mode.vue (2)

3-27: Consider separate v-model values for clearer demo behavior

Both filter-mode examples bind to the same value, so selecting in one control will update the other. That’s valid Vue usage, but in docs it can look surprising to readers comparing “场景 1” vs “场景 2” independently. Consider using value1 / value2 (or similar) so each scenario is isolated, unless the shared state is intentional and documented.


54-56: Align control and dropdown widths (optional visual tweak)

You set the dropdown width to 200px via drop-style, while the base-select itself is 280px wide. This will render a narrower dropdown than the trigger. If that’s not intentional, you might want to make these widths consistent (e.g., both 200px or both 280px) or use a shared variable/class for easier tuning.

examples/sites/demos/mobile-first/app/base-select/show-alloption.vue (1)

7-28: Initialize value as an array for multiple mode

For a multi‑select, v-model is typically an array of selected values; initializing value as a string can be confusing and may not match the expected type for multiple mode. Consider:

-      value: ''
+      value: []

Please confirm against the TinyBaseSelect multiple‑mode API; if it indeed expects an array, this change will make the demo more accurate.

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

3-10: Consider separate v-models per scenario for clarity

Both selects share the same value and options. It works here (no options), but giving each scenario its own value (and, if needed, its own options) would avoid hidden coupling and make later edits to one scenario less error‑prone.

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

30-33: Consider making width more flexible for mobile-first layout

Using a fixed width: 280px works for the example, but for a mobile-first demo you might consider a more flexible rule (e.g., width: 100%; max-width: 280px;) so it better adapts to varying screen sizes.

examples/sites/demos/mobile-first/app/base-select/events.vue (2)

58-99: Consider accepting event parameters to improve demo value.

The event handlers currently don't accept or display any parameters. For better educational value, consider showing what data each event provides (e.g., the new value in change, the removed tag in removeTag, the visibility state in visibleChange).

Example enhancement:

-    change() {
+    change(value) {
       TinyModal.message({
-        message: '触发 change 事件',
+        message: `触发 change 事件,新值: ${JSON.stringify(value)}`,
         status: 'info'
       })
     },

108-111: Remove unused p selector.

The template contains no <p> elements, so this style rule is unused.

 [data-tag='tiny-base-select'] {
   width: 280px;
 }
-p {
-  font-size: 14px;
-  line-height: 1.5;
-}
examples/sites/demos/mobile-first/app/base-select/collapse-tags.vue (1)

3-3: Consider using CSS for spacing instead of <br /> tags.

Multiple <br /> tags are used for vertical spacing throughout the template. For better maintainability and semantics, consider using CSS margins or padding on the container divs instead.

Example refactor:

 <template>
   <div>
-    <br />
-    <div>场景 1:collapse-tags 折叠</div>
-    <br />
+    <div class="demo-section">场景 1:collapse-tags 折叠</div>
     <tiny-base-select v-model="value1" :show-proportion="true" multiple collapse-tags>
       <tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
     </tiny-base-select>
-    <br />
-    <br />
-    <div>场景 2:hover-expand 折叠</div>
-    <br />
+    <div class="demo-section">场景 2:hover-expand 折叠</div>
     <tiny-base-select v-model="value2" multiple hover-expand>
       <tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
     </tiny-base-select>
-    <br />
-    <br />
   </div>
 </template>

Then add to styles:

.demo-section {
  margin-top: 16px;
  margin-bottom: 8px;
}

Also applies to: 5-5, 9-10, 12-12, 16-17

examples/sites/demos/mobile-first/app/base-select/slot-panel.vue (2)

28-29: Initialize value2 as an array for the multiple-select case

For multiple mode, v-model is typically an array of selected values. Here value2 is initialized as an empty string, which can be confusing and may not match consumers’ expectations.

Consider changing the data initialization:

-      value: '',
-      value2: '',
-      value3: '',
+      value: '',
+      value2: [],
+      value3: '',

Also applies to: 92-94


134-141: Add defensive checks in filterMethod and filter to avoid edge-case runtime errors

If filterMethod is called before treeRef is set, or if a tree node lacks a label field, this code could throw. A small guard keeps the demo more robust without changing intended behavior:

-    filterMethod(value) {
-      this.$refs.treeRef.filter(value)
-    },
-    filter(value, data) {
-      if (!value) return true
-
-      return data.label.includes(value)
-    }
+    filterMethod(value) {
+      if (this.$refs.treeRef) {
+        this.$refs.treeRef.filter(value)
+      }
+    },
+    filter(value, data) {
+      if (!value) return true
+
+      return data && data.label ? data.label.includes(value) : false
+    }
examples/sites/demos/mobile-first/app/base-select/multiple-mix.vue (3)

12-22: Confirm shared v-model across all selects

All tiny-base-select instances are bound to the same formData.select1 array, so changing any one of them updates all others. If the intention is to have truly independent demos per section/size, consider giving each example its own field in formData (e.g., selectMini, selectSmall, etc.).

Also applies to: 30-33, 38-41, 46-49, 57-60, 68-71, 79-82


3-8: Use CSS spacing instead of repeated <br />/&nbsp; where possible

The layout relies heavily on multiple <br /> tags and <p>&nbsp;</p> for vertical spacing. For readability and easier tuning later, consider moving most of this spacing into CSS (e.g., margins on .custom-form or wrapper elements) and keeping the template focused on structure.

Also applies to: 16-17, 24-27, 35-36, 43-45, 50-53, 61-65, 72-75, 83-85


143-155: Re-evaluate fixed 350px width for mobile-first demo

.demo-box is constrained to a fixed width: 350px;. For a mobile-first demo, you might want to make this responsive (e.g., width: 100%; max-width: 350px;) so it adapts better across devices while still approximating a phone width.

examples/sites/demos/mobile-first/app/base-select/binding-obj.vue (1)

3-8: Use a stable key and render the bound object more readably in the demo

Two small suggestions for the demo clarity:

  1. v-for key:
    • :key="index" works but is not ideal; a stable key like the option id avoids potential update pitfalls and better reflects best practice.
  2. Displaying value:
    • value is an object, so {{ value }} will show [object Object]. For a binding-obj demo, rendering JSON will make the effect clearer to readers.

You could do something like:

-    <tiny-base-select v-model="value" value-key="val">
-      <tiny-option v-for="(item, index) in options" :key="index" :label="item.text" :value="item.obj"> </tiny-option>
-    </tiny-base-select>
-    <p class="value">
-      {{ value }}
-    </p>
+    <tiny-base-select v-model="value" value-key="val">
+      <tiny-option v-for="item in options" :key="item.obj.id" :label="item.text" :value="item.obj"> </tiny-option>
+    </tiny-base-select>
+    <p class="value">
+      {{ JSON.stringify(value, null, 2) }}
+    </p>
examples/sites/demos/mobile-first/app/grid-select/radio-bigdata.vue (2)

29-38: Optionally avoid writing directly to the global window namespace

window.gridSelectRadioBigData = data.length is convenient but slightly pollutes the global namespace and risks name collisions.

If this isn’t constrained by existing tests, consider namespacing under a single demo object instead:

-    window.gridSelectRadioBigData = data.length
+    window.__tinyVueDemos = window.__tinyVueDemos || {}
+    window.__tinyVueDemos.gridSelectRadioBigData = data.length

This keeps globals grouped while preserving the ability to inspect the value from outside.


42-45: Make container width more responsive for mobile-first layout

For a “mobile-first” demo, a fixed width: 350px can be slightly rigid on narrower or wider screens. You can keep the same max width while allowing it to shrink or grow with the viewport:

-#radio-bigdata {
-  width: 350px;
-}
+#radio-bigdata {
+  width: 100%;
+  max-width: 350px;
+}

This preserves the current visual cap but behaves better across device widths.

examples/sites/demos/pc/app/grid-select/basic-usage.vue (1)

44-58: Consider extracting shared data to reduce duplication.

The data arrays in gridOpSingle and gridOpMulti are identical. For demo purposes this is acceptable, but you could extract the shared data to a constant for maintainability.

 data() {
+   const sharedData = [
+     { id: '001', area: '华南区', province: '广东省', city: '广州市' },
+     { id: '002', area: '华南区', province: '广东省', city: '深圳市' },
+     { id: '003', area: '华南区', province: '广东省', city: '珠海市' },
+     { id: '004', area: '华南区', province: '广东省', city: '佛山市' },
+     { id: '005', area: '华南区', province: '广东省', city: '中山市' }
+   ]
    return {
      value: '',
      value2: [],
      gridOpSingle: {
-       data: [
-         { id: '001', area: '华南区', province: '广东省', city: '广州市' },
-         ...
-       ],
+       data: sharedData,
        columns: [...]
      },
      gridOpMulti: {
-       data: [
-         { id: '001', area: '华南区', province: '广东省', city: '广州市' },
-         ...
-       ],
+       data: sharedData,
        columns: [...]
      }
    }
  }
examples/sites/demos/mobile-first/app/base-select/copy-multi.vue (1)

7-14: Avoid duplicate ref and shared model between different demo scenes

Both Scene 2 and Scene 3 use the same ref="selectCopyable" and the same v-model="value2". While this works, it makes $refs.selectCopyable an array and couples the states of two separate “scenes”, which is confusing for documentation.

Recommend giving Scene 3 its own ref and state so behavior is easier to reason about:

-    <p>场景 2:多选一键复制所有标签</p>
-    <tiny-base-select ref="selectCopyable" v-model="value2" multiple copyable>
+    <p>场景 2:多选一键复制所有标签</p>
+    <tiny-base-select ref="selectCopyable" v-model="value2" multiple copyable>
       <tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
     </tiny-base-select>
     <p>场景 3:多选设置复制文本分隔符</p>
-    <tiny-base-select ref="selectCopyable" v-model="value2" multiple copyable text-split="/">
+    <tiny-base-select ref="selectCopyableSplit" v-model="value3" multiple copyable text-split="/">
       <tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
     </tiny-base-select>

And in data():

-      value1: ['选项 1'],
-      value2: ['选项 1', '选项 2'],
-      copyValue: ''
+      value1: ['选项 1'],
+      value2: ['选项 1', '选项 2'],
+      value3: ['选项 1', '选项 2'],
+      copyValue: ''

If you don’t need $refs at all, another option is simply to drop both ref attributes.

examples/sites/demos/mobile-first/app/base-select/slot-default.vue (2)

6-17: Consider extracting the duplicated option content.

The option rendering logic (label span + conditional tag) is duplicated in lines 8-11 and 14-15. Extracting this into a named slot or computed template would improve maintainability and follow DRY principles.

Example refactor approach—use a named slot or component:

     <tiny-base-select v-model="value1" popper-class="slot-default">
       <template v-for="item in options1">
-        <tiny-tooltip v-if="item.tip" :content="item.tip" placement="right" effect="light" :key="item.value">
-          <tiny-option :label="item.label" :value="item.value">
-            <span class="left">{{ item.label }}</span>
-            <tiny-tag v-if="item.tag" type="danger" effect="light" size="small">{{ item.tag }}</tiny-tag>
-          </tiny-option>
-        </tiny-tooltip>
-        <tiny-option v-if="!item.tip" :key="item.value" :label="item.label" :value="item.value">
+        <component :is="item.tip ? 'tiny-tooltip' : 'div'" 
+                   v-bind="item.tip ? { content: item.tip, placement: 'right', effect: 'light' } : {}"
+                   :key="item.value">
+          <tiny-option :label="item.label" :value="item.value">
             <span class="left">{{ item.label }}</span>
             <tiny-tag v-if="item.tag" type="danger" effect="light" size="small">{{ item.tag }}</tiny-tag>
           </tiny-option>
-        </tiny-option>
+        </component>
       </template>
     </tiny-base-select>

86-95: Document the magic numbers in global styles.

The max-height 224px and option height 54px appear to be calculated values but lack explanation. Adding a comment clarifying the intention (e.g., "Shows 4 items at 54px each plus spacing") would improve maintainability.

 .double-row {
   &.tiny-select-dropdown .tiny-select-dropdown__wrap {
+    /* Max height to show ~4 options (4 × 54px + spacing) */
     max-height: 224px;
     .tiny-option {
+      /* Increased height to accommodate two-line content */
       height: 54px;
     }
   }
 }
examples/sites/demos/mobile-first/app/base-select/copy-single.vue (2)

3-14: Consider decoupling scenarios 1 and 2.

Both scenarios share the same v-model="value1" binding. Changes in one select will affect the other, which may confuse users trying to understand independent copy behavior per scenario.

If independent scenarios are intended, apply this diff:

     <p>场景 1:单选无需配置可复制</p>
-    <tiny-base-select v-model="value1" :options="options1"> </tiny-base-select>
+    <tiny-base-select v-model="value1" :options="options1Copy"> </tiny-base-select>

And update the data to include a copy:

data() {
  return {
    options1Copy: [
      { value: '选项 1', label: '北京' },
      { value: '选项 2', label: '上海' },
      { value: '选项 3', label: '天津' },
      { value: '选项 4', label: '重庆' },
      { value: '选项 5', label: '深圳' }
    ],
    // ... rest of data
  }
}

60-117: Consider extracting US states to a constant.

The hardcoded states list (50+ items) clutters the mounted hook and reduces maintainability. Consider extracting to a module constant or data file.

Create a separate file constants/states.js:

export const US_STATES = [
  'Alabama',
  'Alaska',
  // ... rest of states
  'Wyoming'
]

Then import and use:

+import { US_STATES } from '@/constants/states'
+
 export default {
   // ...
   mounted() {
-    const states = [
-      'Alabama',
-      // ... all states
-    ]
-
-    this.list = states.map((item) => {
+    this.list = US_STATES.map((item) => {
       return { value: item, label: item }
     })
   }
 }
examples/sites/demos/mobile-first/app/base-select/remote-method.vue (1)

196-260: Remote methods 1–5 share identical logic — consider extracting helper and tightening query check

remoteMethod1remoteMethod5 are almost identical apart from the loading/option fields and timeout values. For maintainability and to avoid copy‑paste drift, you could:

  • Extract a small helper that accepts (query, loadingPropName, optionsPropName, delay) and reuse it across the five methods.
  • Optionally tighten the condition from query !== undefined to something like query && query.trim() !== '' if you want to avoid returning the full list on empty input (which is a common remote-search pattern). If showing all results on empty query is intentional, you can leave it as-is.

Example sketch:

methods: {
  doRemoteSearch(query, loadingKey, optionsKey, delay = 200) {
    if (!query || !query.trim()) {
      this[optionsKey] = []
      return
    }
    this[loadingKey] = true
    setTimeout(() => {
      this[loadingKey] = false
      const q = query.toLowerCase()
      this[optionsKey] = this.list.filter(item => item.label.toLowerCase().includes(q))
    }, delay)
  },
  remoteMethod1(query) {
    this.doRemoteSearch(query, 'loading1', 'options1', 200)
  },
  // ...
}

This is optional, but would reduce duplication and make future tweaks to the remote-search behavior much simpler.

examples/sites/demos/mobile-first/app/base-select/cache-usage.vue (1)

23-42: Sync cacheValue on mount for a more consistent demo state

cacheValue is only updated inside cacheChange, so if TinyBaseSelect restores a cached value on mount via cache-op, the select and the displayed cache text can be out of sync until the user changes the value again. Calling cacheChange once on mount keeps them aligned without changing behavior.

You can do this:

 export default {
   components: {
     TinyBaseSelect
   },
   data() {
     return {
       cacheOp: {
         key: 'test'
       },
       cacheValue: '',
       options: [
         { value: '选项 1', label: '北京' },
         { value: '选项 2', label: '上海' },
         { value: '选项 3', label: '天津' },
         { value: '选项 4', label: '重庆' },
         { value: '选项 5', label: '深圳' }
       ],
       value: '选项 3'
     }
   },
+  mounted() {
+    this.cacheChange()
+  },
   methods: {
     cacheChange() {
       this.cacheValue = window.localStorage.getItem(`tiny_memorize_${this.cacheOp.key}`)
     }
   }
 }
examples/sites/demos/mobile-first/app/base-select/memoize-usage.vue (1)

23-31: Avoid repeating the Memorize key and storage key literal

The string 'test456' is used both in the Memorize constructor and inside the hardcoded localStorage key 'tiny_memorize_test456'. If you ever change the key in one place and forget the other, the demo will silently desynchronize from the cache.

You can centralize the key definitions like this:

 import { TinyBaseSelect, TinyOption } from '@opentiny/vue'
 import { Memorize } from '@opentiny/utils'
 
-const MemorizeInstance = new Memorize({ key: 'test456' })
-
-const options = MemorizeInstance.assemble([
+const MEMOIZE_KEY = 'test456'
+const STORAGE_KEY = `tiny_memorize_${MEMOIZE_KEY}`
+const MemorizeInstance = new Memorize({ key: MEMOIZE_KEY })
+
+const options = MemorizeInstance.assemble([
   { value: '选项 1', label: '北京' },
   { value: '选项 2', label: '上海' },
   { value: '选项 3', label: '天津' },
   { value: '选项 4', label: '重庆' },
   { value: '选项 5', label: '深圳' }
 ])
@@
   methods: {
     clickItem(value) {
       MemorizeInstance.updateByKey(value)
-      this.cacheValue = window.localStorage.getItem('tiny_memorize_test456')
+      this.cacheValue = window.localStorage.getItem(STORAGE_KEY)
     }
   },
   mounted() {
-    window.localStorage.setItem('tiny_memorize_test456', '')
+    window.localStorage.setItem(STORAGE_KEY, '')
   }
 }

Also applies to: 46-53

examples/sites/demos/mobile-first/app/base-select/disabled.vue (1)

6-8: Consider removing unnecessary autocomplete attribute.

The autocomplete attribute on a disabled select has no practical effect since users cannot interact with it. Consider removing it for clarity.

-    <tiny-base-select v-model="value1" disabled autocomplete>
+    <tiny-base-select v-model="value1" disabled>
examples/sites/demos/mobile-first/app/base-select/webdoc/base-select.js (1)

447-487: Align slot demo names with their actual purpose

Two slot demos have inconsistent EN names:

  • Line 450: 'Predix slot' is likely a typo for “Prefix slot”.
  • Line 486: EN name for slot-label is 'Reference slot', which duplicates the previous demo and does not match the label-slot description.

Suggested tweaks:

      name: {
         'zh-CN': '输入框前缀插槽',
-        'en-US': 'Predix slot'
+        'en-US': 'Prefix slot'
      },
...
      name: {
         'zh-CN': '标签插槽',
-        'en-US': 'Reference slot'
+        'en-US': 'Label slot'
      },
examples/sites/demos/mobile-first/app/base-select/webdoc/base-select.en.md (1)

1-7: Doc is correct but very minimal; consider adding usage details

The EN doc is syntactically fine but only contains a one-line description. Given the large set of demos you’ve added, consider briefly outlining key features (single/multiple select, search, remote, slots) and linking to representative demos so the page is more informative.

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

21-33: Avoid JSON.parse in buildOptions for 100k items

Using JSON.parse inside the Array.from map for 100,000 items adds avoidable overhead in a demo that’s already stressing large data.

You can generate the same data more cheaply with object literals:

-const buildOptions = () =>
-  Array.from({ length: 100000 }).map((item, i) => JSON.parse(`{"value":"选项 ${i}","label":"北京 ${i}"}`))
+const buildOptions = () =>
+  Array.from({ length: 100000 }, (item, i) => ({
+    value: `选项 ${i}`,
+    label: `北京 ${i}`
+  }))

If you want to further reduce per-instance cost, you could also prebuild once:

-const buildOptions = () =>
-  Array.from({ length: 100000 }, (item, i) => ({ ... }))
+const OPTIONS = Array.from({ length: 100000 }, (item, i) => ({ ... }))
...
-      options: buildOptions()
+      options: OPTIONS
examples/sites/demos/mobile-first/app/base-select/basic-usage.vue (1)

1-47: Basic usage demo is clear; optional small optimization for icons

The two scenarios (slot-based vs options-based) are well structured and the bindings look correct.

If you care about tiny optimizations even in demos, you could avoid calling iconFile() repeatedly by reusing a single icon instance:

 data() {
   return {
-      options: [
-        { value: '选项 1', label: '北京', icon: iconFile() },
-        { value: '选项 2', label: '上海', icon: iconFile() },
-        { value: '选项 3', label: '天津', icon: iconFile() },
-        { value: '选项 4', label: '重庆', icon: iconFile() },
-        { value: '选项 5', label: '深圳', icon: iconFile() }
-      ],
+      options: (() => {
+        const fileIcon = iconFile()
+        return [
+          { value: '选项 1', label: '北京', icon: fileIcon },
+          { value: '选项 2', label: '上海', icon: fileIcon },
+          { value: '选项 3', label: '天津', icon: fileIcon },
+          { value: '选项 4', label: '重庆', icon: fileIcon },
+          { value: '选项 5', label: '深圳', icon: fileIcon }
+        ]
+      })(),
       value: ''
   }
 }
examples/sites/demos/mobile-first/app/base-select/popup-style-position.vue (1)

1-40: Popup style/position demo is correct; be aware .drop is global

The select configuration and data look good, and using popper-class="drop" matches the global .drop style.

Note that the second <style> block is unscoped, so .drop will affect any dropdown using that class across the docs site. That’s likely intentional for a shared demo style, just keep it in mind if other components later reuse drop.

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

1-124: Remote init/query demo logic is fine; clean up unused duplicate refs

The initQuery and remoteMethod implementations are consistent and make sense for a large remote dataset, and the grid configs look correct.

Two small cleanups you might consider:

  1. Both <tiny-grid-select> elements use ref="select", but $refs.select is never read, so the refs can be removed:
-    <tiny-grid-select
-      ref="select"
+    <tiny-grid-select
       v-model="radioValue1"
       ...
-    <tiny-grid-select
-      ref="select"
+    <tiny-grid-select
       v-model="radioValue2"
       ...
  1. Since created() immediately overwrites allData, you can initialize it directly there and drop the allData: [] from data() for slightly clearer intent, or vice versa (build it in data() and remove the created hook).
examples/sites/demos/mobile-first/app/base-select/all-text.vue (1)

27-33: Minor inconsistency: option values skip from 4 to 6.

The options array skips 选项 5, going directly from 选项 4 to 选项 6. If this is intentional for demo purposes, consider adding a comment; otherwise, this appears to be a typo.

         { value: '选项 4', label: '龙须面' },
-        { value: '选项 6', label: '螺蛳粉' }
+        { value: '选项 5', label: '螺蛳粉' }
examples/sites/demos/mobile-first/app/base-select/allow-create.vue (1)

19-42: Remove unused imports, components, and data properties.

Several imports and data properties are not used in this demo:

  • Imports: TinyInput, TinyButton, TinyDialogBox, TinyModal
  • Components: TinyInput, TinyButton, TinyDialogBox
  • Data: boxVisibility, optionLabel, optionValue
-import { TinyBaseSelect, TinyOption, TinyInput, TinyButton, TinyDialogBox, TinyModal } from '@opentiny/vue'
+import { TinyBaseSelect, TinyOption } from '@opentiny/vue'

 export default {
   components: {
     TinyBaseSelect,
-    TinyOption,
-    TinyInput,
-    TinyButton,
-    TinyDialogBox
+    TinyOption
   },
   data() {
     return {
       options: [
         { value: '选项 1', label: '北京' },
         { value: '选项 2', label: '上海' },
         { value: '选项 3', label: '天津' },
         { value: '选项 4', label: '重庆' },
         { value: '选项 5', label: '深圳' }
       ],
-      value: '',
-      boxVisibility: false,
-      optionLabel: '',
-      optionValue: ''
+      value: ''
     }
   }
 }
examples/sites/demos/mobile-first/app/grid-select/extra-query-params.vue (1)

100-102: Remove unused parameter from loadChildren method.

The value parameter in loadChildren(value, extraQueryParams) is unused. Consider removing it for clarity, or document why it's required by the API.

-    loadChildren(value, extraQueryParams) {
+    loadChildren(extraQueryParams) {
       return this.filterChildren(extraQueryParams)
     },
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6746608 and d0c7497.

📒 Files selected for processing (56)
  • examples/docs/newsrc/utils/componentsDoc.js (1 hunks)
  • examples/sites/demos/apis/grid-select.js (13 hunks)
  • examples/sites/demos/mobile-first/app/base-select/all-text.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/allow-create.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/automatic-dropdown.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/basic-usage.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/binding-obj.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/cache-usage.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/clear-no-match-value.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/clearable.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/collapse-tags.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/copy-multi.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/copy-single.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/disabled.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/events.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/filter-method.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/filter-mode.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/hide-drop.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/is-drop-inherit-width.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/manual-focus-blur.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/map-field.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/memoize-usage.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/multiple-mix.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/multiple.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/native-properties.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/no-data-text.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/optimization.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/option-group.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/popup-style-position.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/remote-method.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/show-alloption.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/show-tip.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/size.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/slot-default.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/slot-empty.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/slot-footer.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/slot-label.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/slot-panel.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/slot-prefix.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/slot-reference.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/tag-type.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/webdoc/base-select.cn.md (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/webdoc/base-select.en.md (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/webdoc/base-select.js (1 hunks)
  • examples/sites/demos/mobile-first/app/grid-select/basic-usage.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/grid-select/config.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/grid-select/extra-query-params.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/grid-select/init-query.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/grid-select/radio-bigdata.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/grid-select/remote.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/grid-select/webdoc/grid-select.cn.md (1 hunks)
  • examples/sites/demos/mobile-first/app/grid-select/webdoc/grid-select.en.md (1 hunks)
  • examples/sites/demos/mobile-first/app/grid-select/webdoc/grid-select.js (1 hunks)
  • examples/sites/demos/mobile-first/menus.js (1 hunks)
  • examples/sites/demos/pc/app/grid-select/basic-usage-composition-api.vue (2 hunks)
  • examples/sites/demos/pc/app/grid-select/basic-usage.vue (3 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 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/base-select/map-field.vue
  • examples/sites/demos/mobile-first/app/base-select/is-drop-inherit-width.vue
  • examples/sites/demos/mobile-first/app/base-select/filter-method.vue
  • examples/sites/demos/mobile-first/app/base-select/disabled.vue
  • examples/sites/demos/mobile-first/app/base-select/hide-drop.vue
  • examples/sites/demos/mobile-first/app/base-select/collapse-tags.vue
  • examples/sites/demos/mobile-first/app/base-select/show-alloption.vue
  • examples/sites/demos/mobile-first/app/base-select/tag-type.vue
  • examples/sites/demos/mobile-first/app/base-select/optimization.vue
  • examples/sites/demos/mobile-first/app/base-select/memoize-usage.vue
  • examples/sites/demos/mobile-first/app/base-select/events.vue
  • examples/sites/demos/mobile-first/app/base-select/clearable.vue
  • examples/sites/demos/mobile-first/app/base-select/native-properties.vue
  • examples/sites/demos/mobile-first/app/base-select/show-tip.vue
  • examples/sites/demos/mobile-first/app/base-select/popup-style-position.vue
  • examples/sites/demos/mobile-first/app/base-select/slot-label.vue
  • examples/sites/demos/mobile-first/app/base-select/slot-footer.vue
  • examples/sites/demos/mobile-first/app/base-select/basic-usage.vue
  • examples/sites/demos/mobile-first/app/base-select/multiple.vue
  • examples/sites/demos/mobile-first/app/base-select/no-data-text.vue
  • examples/sites/demos/mobile-first/app/base-select/slot-reference.vue
  • examples/sites/demos/mobile-first/app/base-select/slot-panel.vue
  • examples/sites/demos/mobile-first/app/base-select/cache-usage.vue
  • examples/sites/demos/mobile-first/app/base-select/size.vue
  • examples/sites/demos/mobile-first/app/base-select/slot-default.vue
  • examples/sites/demos/mobile-first/app/base-select/allow-create.vue
  • examples/sites/demos/mobile-first/app/base-select/binding-obj.vue
  • examples/sites/demos/mobile-first/app/base-select/clear-no-match-value.vue
  • examples/sites/demos/mobile-first/app/grid-select/config.vue
  • examples/sites/demos/mobile-first/app/base-select/option-group.vue
  • examples/sites/demos/mobile-first/app/base-select/slot-prefix.vue
  • examples/sites/demos/mobile-first/app/base-select/filter-mode.vue
  • examples/sites/demos/mobile-first/app/base-select/copy-single.vue
📚 Learning: 2024-11-25T03:24:05.740Z
Learnt from: Davont
Repo: opentiny/tiny-vue PR: 2513
File: packages/vue/src/huicharts/huicharts-sunburst/src/chart-sunburst.vue:30-32
Timestamp: 2024-11-25T03:24:05.740Z
Learning: 在位于`packages/vue/src/huicharts/huicharts-sunburst/src/chart-sunburst.vue`的组件中,当使用`chart-core`时,应删除错误的`option`定义,使用`chart-core`中的`huiChartOption`。

Applied to files:

  • examples/sites/demos/mobile-first/app/base-select/option-group.vue
⏰ 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)

Comment on lines +57 to +69
customFilterMethod(searchValue) {
const customFilterRef = this.$refs.customFilterRef
if (searchValue) {
customFilterRef.state.cachedOptions.forEach((item) => {
item.state.visible = item.label.includes(searchValue)
})
} else {
customFilterRef.state.cachedOptions.forEach((item) => {
item.state.visible = true
})
}
}
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

Avoid directly mutating internal component state.

The custom filter method accesses and mutates internal component state (customFilterRef.state.cachedOptions and item.state.visible). This approach:

  • Violates encapsulation and couples the demo to internal implementation details
  • Is brittle and may break with future component updates
  • Creates inconsistency with the template's v-show directive which checks item.filter instead of item.state.visible

Consider refactoring to use a data-driven approach that doesn't rely on internal state:

   customFilterMethod(searchValue) {
-    const customFilterRef = this.$refs.customFilterRef
-
-    if (searchValue) {
-      customFilterRef.state.cachedOptions.forEach((item) => {
-        item.state.visible = item.label.includes(searchValue)
-      })
-    } else {
-      customFilterRef.state.cachedOptions.forEach((item) => {
-        item.state.visible = true
-      })
-    }
+    this.options.forEach((item) => {
+      item.filter = searchValue ? !item.label.includes(searchValue) : false
+    })
   }

Then ensure the v-show directive correctly references this property (which it already does at line 25).

🤖 Prompt for AI Agents
In examples/sites/demos/mobile-first/app/base-select/filter-method.vue around
lines 57–69, the customFilterMethod mutates internal component state
(customFilterRef.state.cachedOptions and item.state.visible); instead, compute
and set a public/filter property on each option (e.g., item.filter) or update a
component-level reactive map keyed by option id/label, and have the template
read that public property (v-show already checks item.filter at line 25).
Replace writes to item.state.visible with writes to the public property (or your
reactive map) and ensure the else branch sets the public property to true for
all options; do not access or mutate customFilterRef.state.*.

:key="item.value"
:label="item.label"
:value="item.value"
:required="item.required"
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:

#!/bin/bash
# Search for required prop in base-select and option component implementations
echo "=== Searching for required prop in base-select component ==="
fd -t f 'base-select' packages/vue/src/ | head -20

echo -e "\n=== Searching for required prop in option component ==="
fd -t f 'option' packages/vue/src/ | head -20

echo -e "\n=== Looking for required prop usage in base-select ==="
rg -n 'required' packages/vue/src/base-select/ -A 2 -B 2

echo -e "\n=== Looking for required prop usage in option ==="
rg -n 'required' packages/vue/src/option/ -A 2 -B 2

Repository: opentiny/tiny-vue

Length of output: 178


🏁 Script executed:

#!/bin/bash
# Look for other demos using required prop to understand the pattern
echo "=== Other demos using required prop ==="
rg -l 'required.*true' examples/sites/demos/ --type vue

# Look for the actual file we're reviewing
echo -e "\n=== Content of multiple.vue around lines 20 and 80 ==="
cat -n examples/sites/demos/mobile-first/app/base-select/multiple.vue | sed -n '1,30p'
cat -n examples/sites/demos/mobile-first/app/base-select/multiple.vue | sed -n '75,85p'

Repository: opentiny/tiny-vue

Length of output: 178


🌐 Web query:

TinyVue base-select option required prop documentation

💡 Result:

Do you mean the BaseSelect component in TinyVue and its "required" prop (making the select required), or an "required" field on individual option objects?


🌐 Web query:

opentiny/tiny-vue TinyOption TinyBaseSelect required property support

💡 Result:

Short answer: TinyOption / TinyBaseSelect (tiny-select) do not expose a built-in HTML-style required prop that enforces validation by the browser. The component API/examples show using v-model to read the value, and form validation must be implemented externally (check v-model, use your form library or custom rules) rather than relying on a built-in required attribute. [1][2]

What to do:

  • Validate the select value yourself before submit (check the component's v-model).
  • Or integrate with your form-validation solution (e.g., VeeValidate/async validators) and treat the tiny-select value as the field to validate.
    References: tiny-vue repo and docs/examples (tiny-select / tiny-option usage). [1][2]

Sources
[1] opentiny/tiny-vue (repository).
[2] OpenTiny / TinyVue docs — tiny-select / example usage.


Remove unsupported required prop from TinyOption elements.

The required prop used on lines 20 and 80 is not officially supported by TinyOption/TinyBaseSelect. Form validation must be implemented externally using v-model binding and custom validation logic rather than relying on a component-level required attribute.

🤖 Prompt for AI Agents
In examples/sites/demos/mobile-first/app/base-select/multiple.vue around lines
20 and 80, remove the unsupported :required="item.required" prop from the
TinyOption/TinyBaseSelect elements; instead rely on the component's v-model
binding and implement external validation in the parent (e.g., validate the
v-model value in a computed property, watcher, or form submit handler and show
an error state/tooltip) so that selection is enforced without using the
unsupported component-level required attribute.

Comment on lines +71 to +72
value1: [],
value2: '',
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 the v-model type mismatches.

The data initialization types don't match their usage patterns:

  • value1 is initialized as an array but used for single-select (line 19), which expects a string or number.
  • value2 is initialized as a string but used for multi-select (lines 5, 33, 47), which expects an array.

This will cause the demo to malfunction.

Apply this diff to fix the type mismatches:

-      value1: [],
-      value2: '',
+      value1: '',
+      value2: [],
📝 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
value1: [],
value2: '',
value1: '',
value2: [],
🤖 Prompt for AI Agents
In examples/sites/demos/mobile-first/app/base-select/option-group.vue around
lines 71-72, the data initializations have mismatched types: value1 is
initialized as an array but is used as a single-select, and value2 is
initialized as a string but is used as a multi-select. Fix by initializing
value1 to an empty string (or null/number consistent with the single-select
value type) and initializing value2 to an empty array so both v-model usages
have matching types.

Comment on lines +1 to +34
<template>
<tiny-base-select v-model="value" multiple show-overflow-tooltip style="width: 200px">
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
</template>

<script>
import { TinyBaseSelect, TinyOption } from '@opentiny/vue'
export default {
components: {
TinyBaseSelect,
TinyOption
},
data() {
return {
options: [
{ value: '选项 1', label: '北京' },
{ value: '选项 2', label: '上海' },
{ value: '选项 3', label: '天津' },
{ value: '选项 4', label: '重庆' },
{ value: '选项 5', label: '深圳' }
],
value: ''
}
}
}
</script>

<style lang="less" scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
</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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find all multi-select component usage in base-select demos
find examples/sites/demos/mobile-first/app/base-select -name "*.vue" -type f -exec grep -l "multiple" {} \;

Repository: opentiny/tiny-vue

Length of output: 178


🏁 Script executed:

#!/bin/bash
# Check how value is initialized in files that use multiple attribute
find examples/sites/demos/mobile-first/app/base-select -name "*.vue" -type f | while read file; do
  if grep -q "multiple" "$file"; then
    echo "=== File: $file ==="
    grep -A 20 "data()" "$file" | grep -A 10 "value.*:"
  fi
done

Repository: opentiny/tiny-vue

Length of output: 178


🌐 Web query:

@opentiny/vue BaseSelect multiple mode value initialization documentation

💡 Result:

Short answer: initialize the select's bound value as an array (not a primitive) when using multiple/tags modes — e.g. v-model="selected" where selected = [] or selected = [{...}] / ['id1','id2'] depending on whether your options are objects or primitives. Make sure the items in the initial array match the option shape (or the option-value/key you configured) so the component can match them.

Notes / checklist:

  • multiple / mode="multiple" or mode="tags" => v-model must be an array. Initialize to [] for empty selection. [1]
  • If options are primitive values (strings/numbers) initialize with an array of those primitives. If options are objects, initialize with an array of option objects (or with their value keys if the component supports optionValue/prop). [2]
  • If you bind value prop directly (instead of v-model) you are responsible for updating it on change. [2]

Sources:

  • tiny-vue (OpenTiny) repo / package (install & component library reference). [1]
  • Multiselect/select component docs describing single vs multiple and value initialization (examples showing v-model must be array for multiple). [2]

References:
[1] https://github.com/opentiny/tiny-vue
[2] Vue multiselect/select documentation (value handling / multiple mode).


Change value initialization from empty string to empty array for multi-select mode.

The value is initialized as an empty string (line 24) but should be an empty array [] since the component is in multiple mode (line 2). When using multiple mode with v-model, the bound value must be an array to properly track selected items.

Change line 24 from:

value: ''

to:

value: []
🤖 Prompt for AI Agents
In examples/sites/demos/mobile-first/app/base-select/show-tip.vue around lines 1
to 34, the component is using multiple mode but data.value is initialized as an
empty string on line 24; change the initialization to an empty array so v-model
for multiple select binds to an array (replace the current value initialization
with an empty array) to ensure selected items are tracked correctly.

Comment on lines +36 to +45
<style scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
.select-footer {
text-align: center;
background-color: rgb(207, 243, 232, 0.3);
padding: 8px;
}
</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 | 🔴 Critical

Fix invalid CSS syntax for background color with alpha.

The rgb() function only accepts three parameters (red, green, blue), not four. To include an alpha channel for opacity, use rgba() instead.

Apply this diff to fix the CSS syntax error:

 .select-footer {
   text-align: center;
-  background-color: rgb(207, 243, 232, 0.3);
+  background-color: rgba(207, 243, 232, 0.3);
   padding: 8px;
 }
📝 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
<style scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
.select-footer {
text-align: center;
background-color: rgb(207, 243, 232, 0.3);
padding: 8px;
}
</style>
<style scoped>
[data-tag='tiny-base-select'] {
width: 280px;
}
.select-footer {
text-align: center;
background-color: rgba(207, 243, 232, 0.3);
padding: 8px;
}
</style>
🤖 Prompt for AI Agents
In examples/sites/demos/mobile-first/app/base-select/slot-footer.vue around
lines 36 to 45, the CSS uses rgb(207, 243, 232, 0.3) which is invalid because
rgb() accepts only three parameters; replace it with rgba(207, 243, 232, 0.3)
(or use background-color: rgba(...) with the same numeric values) so the alpha
channel is applied correctly; update the .select-footer background-color
declaration accordingly and keep the rest of the style block unchanged.

@discreted66 discreted66 force-pushed the baseSelectDoc branch 2 times, most recently from 9f26573 to c070798 Compare December 4, 2025 08:15
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: 17

🧹 Nitpick comments (11)
examples/sites/demos/mobile-first/app/base-select/is-drop-inherit-width.vue (1)

1-49: Demo structure is solid; confirm whether shared v-model is desired

Overall the example is clear and correctly wires tiny-base-select / tiny-option with the is-drop-inherit-width prop and scoped width styling. The only thing to double‑check is that both selects bind to the same value model, so selecting in one will immediately change the other—if the intent is just to compare dropdown width behavior this is fine, but if you want independent interaction per scene, consider separate state like valueScene1 / valueScene2.

examples/docs/newsrc/utils/componentsDoc.js (2)

4-5: Consider simplifying the redundant return.

Returning 'grid-select' when path === 'grid-select' is redundant. While it makes the intent explicit (preventing 'grid-select' from matching the startsWith('grid-') check), you could simplify this by adjusting the condition on line 6.

Apply this diff to eliminate the redundancy:

-  if (path === 'grid-select') {
-    return 'grid-select'
-  } else if (path.startsWith('grid-')) {
+  if (path.startsWith('grid-') && path !== 'grid-select') {
     return 'grid'
   } else if (path.startsWith('chart-')) {

3-13: Consider adding documentation to clarify the function's purpose.

The getPath function transforms component paths for API/demo lookup, but its behavior isn't immediately clear from the name or code alone. Adding a brief JSDoc comment would improve maintainability.

Consider adding documentation like:

/**
 * Maps a component path to its base path for API/demo lookup.
 * Special cases: 'grid-select' → 'grid-select', 'grid-*' → 'grid', 'chart-*' → 'chart'
 * @param {string} path - The component path
 * @returns {string} The resolved base path
 */
export const getPath = (path) => {
examples/sites/demos/pc/app/grid-select/basic-usage.vue (1)

28-58: Align multi-select column config and consider de-duplicating grid data

  • The new value2: [] plus gridOpMulti config are consistent with a multi-select scenario and mirror gridOpSingle well.
  • In this file, the multi-select column uses type: 'selection', while the mobile-first demo uses type: 'checkbox' for the same scenario. It would be good to confirm which value is the canonical one for TinyGridSelect multi-select columns and keep both demos in sync.

Also, gridOpSingle.data and gridOpMulti.data are identical. If this pattern repeats elsewhere, you might want to factor the shared data into a single constant to reduce duplication, though it’s not required for a small demo.

examples/sites/demos/mobile-first/app/grid-select/basic-usage.vue (2)

20-60: Verify multi-select column type and keep PC / mobile demos consistent

Here the multi-select grid uses columns: [{ type: 'checkbox', ... }], while the PC demo’s multi-select grid uses type: 'selection'. To avoid confusing users reading both docs, it would be good to:

  • Confirm which column type is officially recommended for TinyGridSelect multi-select.
  • Update both demos to use the same value (either 'checkbox' or 'selection') once confirmed.

Functionally the rest of the data model (value/value2 and gridOpSingle/gridOpMulti) looks sound.


66-70: Consider responsive width for the mobile-first container

Using a fixed width: 280px on #basic-usage is fine for a compact demo, but for a “mobile-first” doc you may want to consider a percentage or max-width-based layout so it scales better across device widths. This is optional and mostly a UX polish choice.

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

196-270: Consider consolidating duplicated remote methods.

All six remoteMethod implementations share nearly identical logic: check if query is defined, set a loading flag, simulate async fetch with setTimeout, filter this.list, then update the corresponding options array. The only variations are the target state variables and timeout durations.

For maintainability, consider extracting a single parameterized helper or using a method factory. However, if explicit separate methods improve demo clarity for documentation purposes, the current approach is acceptable.

Option: Parameterized helper

methods: {
  _fetchRemote(query, scenarioIndex, delay = 200) {
    if (query !== undefined) {
      this[`loading${scenarioIndex}`] = true
      setTimeout(() => {
        this[`loading${scenarioIndex}`] = false
        this[`options${scenarioIndex}`] = this.list.filter((item) =>
          item.label.toLowerCase().includes(query.toLowerCase())
        )
      }, delay)
    } else {
      this[`options${scenarioIndex}`] = []
    }
  },
  remoteMethod1(query) { this._fetchRemote(query, 1, 200) },
  remoteMethod2(query) { this._fetchRemote(query, 2, 200) },
  remoteMethod3(query) { this._fetchRemote(query, 3, 300) },
  remoteMethod4(query) { this._fetchRemote(query, 4, 200) },
  remoteMethod5(query) { this._fetchRemote(query, 5, 200) },
  remoteMethod6(query) { this._fetchRemote(query, 6, 200) },
  changeVal() { /* ... */ },
  resetVal() { /* ... */ }
}
examples/sites/demos/mobile-first/app/base-select/optimization.vue (1)

21-22: Simplify option generation by removing unnecessary JSON.parse.

The buildOptions function uses JSON.parse unnecessarily. Direct object literal construction is clearer and more efficient.

Apply this diff to simplify the code:

-const buildOptions = () =>
-  Array.from({ length: 100000 }).map((item, i) => JSON.parse(`{"value":"选项 ${i}","label":"北京 ${i}"}`))
+const buildOptions = () =>
+  Array.from({ length: 100000 }).map((item, i) => ({ value: `选项 ${i}`, label: `北京 ${i}` }))
examples/sites/demos/mobile-first/app/base-select/copy-multi.vue (1)

38-39: Consider demonstrating distinct selections for each scenario.

Both value1 and value2 are initialized with selected values, but scenarios 2 and 3 (lines 8 and 12) share the same value2 model. This means changing the selection in scenario 2 will automatically update scenario 3 and vice versa, which may not clearly demonstrate each scenario's independent behavior.

If you want to showcase each scenario independently, consider using separate model values:

       value1: ['选项 1'],
       value2: ['选项 1', '选项 2'],
+      value3: ['选项 1', '选项 2', '选项 3'],
       copyValue: ''

And update line 12:

-    <tiny-base-select ref="selectCopyable" v-model="value2" multiple copyable text-split="/">
+    <tiny-base-select ref="selectTextSplit" v-model="value3" multiple copyable text-split="/">
examples/sites/demos/mobile-first/app/base-select/webdoc/base-select.js (2)

127-137: Tighten English description for filterable / filter-method / no-match-text

The current EN text is hard to parse. Consider a clearer sentence structure like the following to better explain each prop:

-        'en-US':
-          '<p>Enable search functionality through the <code>filterable</code> attribute <code>filter-method</code> customize the filtering method <code>no-match-text</code> the text displayed when there is no match between attribute customization and search criteria.</p>\n'
+        'en-US':
+          '<p>Enable search functionality through the <code>filterable</code> attribute. Use <code>filter-method</code> to customize the filtering logic, and <code>no-match-text</code> to define the text shown when no options match the search criteria.</p>\n'

223-233: Remove stray character in optimization English description

The phrase “In n multiple selection mode” contains an extra “n” and reads oddly. Suggest adjusting to:

-        'en-US':
-          '<p>Enable the big data virtual scrolling function through <code>optimization</code>. Supported only when configuring (using the options attribute). In n multiple selection mode, the maximum number of selected items is <code>multiple-limit</code> with a default value of 20. If there are many selected items, it is recommended to turn on <code>collapse-tags</code> for collapsed display. </p>\n'
+        'en-US':
+          '<p>Enable the big data virtual scrolling function through <code>optimization</code>. Supported only when configuring (using the options attribute). In multiple selection mode, the maximum number of selected items is controlled by <code>multiple-limit</code> (default 20). If there are many selected items, it is recommended to turn on <code>collapse-tags</code> for collapsed display. </p>\n'
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d0c7497 and c070798.

📒 Files selected for processing (56)
  • examples/docs/newsrc/utils/componentsDoc.js (1 hunks)
  • examples/sites/demos/apis/grid-select.js (13 hunks)
  • examples/sites/demos/mobile-first/app/base-select/all-text.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/allow-create.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/automatic-dropdown.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/basic-usage.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/binding-obj.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/cache-usage.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/clear-no-match-value.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/clearable.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/collapse-tags.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/copy-multi.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/copy-single.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/disabled.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/events.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/filter-method.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/filter-mode.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/hide-drop.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/is-drop-inherit-width.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/manual-focus-blur.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/map-field.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/memoize-usage.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/multiple-mix.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/multiple.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/native-properties.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/no-data-text.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/optimization.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/option-group.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/popup-style-position.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/remote-method.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/show-alloption.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/show-tip.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/size.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/slot-default.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/slot-empty.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/slot-footer.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/slot-label.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/slot-panel.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/slot-prefix.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/slot-reference.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/tag-type.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/webdoc/base-select.cn.md (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/webdoc/base-select.en.md (1 hunks)
  • examples/sites/demos/mobile-first/app/base-select/webdoc/base-select.js (1 hunks)
  • examples/sites/demos/mobile-first/app/grid-select/basic-usage.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/grid-select/config.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/grid-select/extra-query-params.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/grid-select/init-query.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/grid-select/radio-bigdata.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/grid-select/remote.vue (1 hunks)
  • examples/sites/demos/mobile-first/app/grid-select/webdoc/grid-select.cn.md (1 hunks)
  • examples/sites/demos/mobile-first/app/grid-select/webdoc/grid-select.en.md (1 hunks)
  • examples/sites/demos/mobile-first/app/grid-select/webdoc/grid-select.js (1 hunks)
  • examples/sites/demos/mobile-first/menus.js (1 hunks)
  • examples/sites/demos/pc/app/grid-select/basic-usage-composition-api.vue (2 hunks)
  • examples/sites/demos/pc/app/grid-select/basic-usage.vue (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (37)
  • examples/sites/demos/mobile-first/app/base-select/webdoc/base-select.en.md
  • examples/sites/demos/mobile-first/app/grid-select/webdoc/grid-select.js
  • examples/sites/demos/mobile-first/app/grid-select/webdoc/grid-select.en.md
  • examples/sites/demos/mobile-first/app/base-select/cache-usage.vue
  • examples/sites/demos/mobile-first/app/base-select/disabled.vue
  • examples/sites/demos/mobile-first/app/grid-select/config.vue
  • examples/sites/demos/mobile-first/app/base-select/option-group.vue
  • examples/sites/demos/mobile-first/app/base-select/slot-footer.vue
  • examples/sites/demos/mobile-first/app/base-select/collapse-tags.vue
  • examples/sites/demos/mobile-first/app/base-select/show-alloption.vue
  • examples/sites/demos/mobile-first/app/base-select/clearable.vue
  • examples/sites/demos/mobile-first/app/base-select/slot-empty.vue
  • examples/sites/demos/mobile-first/app/base-select/popup-style-position.vue
  • examples/sites/demos/mobile-first/app/base-select/multiple.vue
  • examples/sites/demos/mobile-first/app/grid-select/radio-bigdata.vue
  • examples/sites/demos/pc/app/grid-select/basic-usage-composition-api.vue
  • examples/sites/demos/mobile-first/app/base-select/filter-method.vue
  • examples/sites/demos/mobile-first/app/base-select/automatic-dropdown.vue
  • examples/sites/demos/mobile-first/app/base-select/show-tip.vue
  • examples/sites/demos/mobile-first/app/base-select/no-data-text.vue
  • examples/sites/demos/mobile-first/app/base-select/events.vue
  • examples/sites/demos/mobile-first/menus.js
  • examples/sites/demos/mobile-first/app/base-select/size.vue
  • examples/sites/demos/mobile-first/app/base-select/allow-create.vue
  • examples/sites/demos/mobile-first/app/base-select/manual-focus-blur.vue
  • examples/sites/demos/mobile-first/app/grid-select/extra-query-params.vue
  • examples/sites/demos/mobile-first/app/grid-select/init-query.vue
  • examples/sites/demos/mobile-first/app/grid-select/remote.vue
  • examples/sites/demos/mobile-first/app/base-select/tag-type.vue
  • examples/sites/demos/mobile-first/app/base-select/filter-mode.vue
  • examples/sites/demos/mobile-first/app/base-select/hide-drop.vue
  • examples/sites/demos/apis/grid-select.js
  • examples/sites/demos/mobile-first/app/base-select/webdoc/base-select.cn.md
  • examples/sites/demos/mobile-first/app/base-select/basic-usage.vue
  • examples/sites/demos/mobile-first/app/base-select/slot-label.vue
  • examples/sites/demos/mobile-first/app/base-select/slot-reference.vue
  • examples/sites/demos/mobile-first/app/grid-select/webdoc/grid-select.cn.md
🧰 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/base-select/map-field.vue
  • examples/sites/demos/mobile-first/app/base-select/binding-obj.vue
  • examples/sites/demos/mobile-first/app/base-select/memoize-usage.vue
  • examples/sites/demos/mobile-first/app/base-select/is-drop-inherit-width.vue
  • examples/sites/demos/mobile-first/app/base-select/slot-default.vue
  • examples/sites/demos/mobile-first/app/base-select/optimization.vue
  • examples/sites/demos/mobile-first/app/base-select/copy-single.vue
  • examples/sites/demos/mobile-first/app/base-select/native-properties.vue
  • examples/sites/demos/mobile-first/app/base-select/clear-no-match-value.vue
  • examples/sites/demos/mobile-first/app/base-select/slot-prefix.vue
  • examples/sites/demos/mobile-first/app/base-select/slot-panel.vue
⏰ 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 (15)
examples/sites/demos/mobile-first/app/base-select/slot-panel.vue (3)

1-26: LGTM!

Scenario 1 (single-select dropdown tree) is well-implemented. The node-click handler correctly updates the selected data with the required properties and hides the panel afterward.


53-79: LGTM!

Scenario 3 (searchable/filterable tree) is well-implemented. The filterMethod correctly delegates to the tree's filter method via ref, and the filter callback properly handles both empty and non-empty search values.

Also applies to: 133-141


146-155: LGTM!

Scoped styles are appropriate for the demo, constraining width and providing consistent paragraph spacing.

examples/sites/demos/pc/app/grid-select/basic-usage.vue (1)

3-14: Template scenes for single / multi-select look correct

The two scenes are clearly labeled and the second tiny-grid-select is correctly bound to its own v-model and grid options; no functional issues from the template side.

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

1-18: Mobile-first template wiring is consistent and clear

The two scenes (single and multi-select) are well separated and both tiny-grid-select instances are correctly bound (value vs value2, gridOpSingle vs gridOpMulti), matching the PC demo behavior.

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

6-38: Demo setup and bindings for clear-no-match-value look solid

The two scenes clearly show single and multi-select behavior: val and multiVal are initialized with non-matching entries, and the options values are consistent with what the selects expect. v-model usage and :clear-no-match-value="true" on both selects align well with the intended behavior for this demo.

If there are any recent API nuances for clear-no-match-value (especially with multi-select) in TinyBaseSelect, please double-check against the latest component docs to ensure the demo text precisely matches actual behavior.

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

282-286: LGTM!

The scoped style correctly constrains the select width using the TinyVue-specific data-tag attribute selector.

examples/sites/demos/mobile-first/app/base-select/native-properties.vue (2)

1-5: LGTM! Demo structure is clear and functional.

The component structure, data setup, and styling are appropriate for a mobile-first demo showcasing native properties of TinyBaseSelect. The v-model binding, placeholder, and name attributes are correctly implemented.

Also applies to: 7-28, 30-34


2-2: Verify the autocomplete attribute handling in TinyBaseSelect.

The autocomplete attribute is passed as a boolean prop on line 2. In standard HTML, autocomplete should have a value like "on", "off", or a specific autocomplete token (e.g., "name", "email"). If TinyBaseSelect renders this directly to the native HTML select element without special prop handling, the boolean attribute may not work as intended. Check the component's prop definition to confirm whether it accepts autocomplete as a boolean and how it renders to the DOM, or use autocomplete="on" if appropriate for your use case.

examples/sites/demos/mobile-first/app/base-select/binding-obj.vue (1)

1-44: LGTM! Clean demo of object-based value binding.

The component correctly demonstrates binding to object values using value-key="val". The pattern of using nested objects with a value-key for comparison is appropriate for this demo scenario.

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

1-42: LGTM! Field mapping demo is correct.

The component correctly demonstrates using value-field and text-field to map custom property names in options. The initial value array correctly references the mapped value field.

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

1-43: LGTM! All-text tag demo is well-structured.

The component effectively demonstrates the difference between the standard all-select behavior and the show-all-text-tag variant. Both scenarios are clearly labeled and correctly configured.

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

1-156: LGTM! Comprehensive multi-scenario demo.

The component effectively demonstrates TinyBaseSelect behavior across multiple form contexts (different sizes, layouts, and display modes). Sharing the same model across all instances is appropriate for this demo's purpose of showing consistent behavior.

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

6-17: Verify key placement for conditional rendering with mixed component types.

The v-for loop conditionally wraps options in TinyTooltip or renders them directly, but both branches use :key="item.value" on different component types. When item.tip exists, the key is on TinyTooltip; otherwise, it's on TinyOption. This means the same key can be associated with different component types, which may cause Vue's diffing algorithm to behave unexpectedly.

Consider moving the key to the template wrapper or ensuring consistent component hierarchy. For example:

<template v-for="item in options1" :key="item.value">
  <tiny-tooltip v-if="item.tip" :content="item.tip" placement="right" effect="light">
    <tiny-option :label="item.label" :value="item.value">
      <span class="left">{{ item.label }}</span>
      <tiny-tag v-if="item.tag" type="danger" effect="light" size="small">{{ item.tag }}</tiny-tag>
    </tiny-option>
  </tiny-tooltip>
  <tiny-option v-else :label="item.label" :value="item.value">
    <span class="left">{{ item.label }}</span>
    <tiny-tag v-if="item.tag" type="danger" effect="light" size="small">{{ item.tag }}</tiny-tag>
  </tiny-option>
</template>
examples/sites/demos/mobile-first/app/base-select/slot-prefix.vue (1)

1-39: LGTM! Clean prefix slot demonstration.

The component correctly demonstrates the prefix slot feature with an icon. The icon registration pattern using iconLocation() is appropriate for the @opentiny/vue-icon library.

<template>
<div>
<p>
场景 1:单选,val 找不到匹配值,val 为: ,<span class="val">{{ val }}</span>
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

Fix stray comma/spacing in scenario 1 description

There’s an extra comma before the <span> that will render oddly and is inconsistent with 场景 2.

-      场景 1:单选,val 找不到匹配值,val 为: ,<span class="val">{{ val }}</span>
+      场景 1:单选,val 找不到匹配值,val 为:<span class="val">{{ val }}</span>
📝 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
场景 1:单选,val 找不到匹配值,val 为: ,<span class="val">{{ val }}</span>
场景 1:单选,val 找不到匹配值,val 为:<span class="val">{{ val }}</span>
🤖 Prompt for AI Agents
In examples/sites/demos/mobile-first/app/base-select/clear-no-match-value.vue
around line 4, the scenario 1 description contains an extra comma before the
<span> which renders oddly and is inconsistent with 场景 2; remove the stray comma
and adjust spacing so the sentence reads "场景 1:单选,val 找不到匹配值,val 为: <span
class=\"val\">{{ val }}</span>" (i.e., no comma immediately before the span and
a single space before it) to match formatting of 场景 2.

Comment on lines +8 to +13
<tiny-base-select ref="selectCopyable" v-model="value2" multiple copyable>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
<p>场景 3:多选设置复制文本分隔符</p>
<tiny-base-select ref="selectCopyable" v-model="value2" multiple copyable text-split="/">
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
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

Fix duplicate ref attribute.

Lines 8 and 12 both use ref="selectCopyable". In Vue, duplicate ref names cause only the last instance to be accessible via this.$refs.selectCopyable, making the earlier reference inaccessible.

Apply this diff to use unique ref names:

-    <tiny-base-select ref="selectCopyable" v-model="value2" multiple copyable>
+    <tiny-base-select ref="selectCopyAllTags" v-model="value2" multiple copyable>
       <tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
     </tiny-base-select>
     <p>场景 3:多选设置复制文本分隔符</p>
-    <tiny-base-select ref="selectCopyable" v-model="value2" multiple copyable text-split="/">
+    <tiny-base-select ref="selectTextSplit" v-model="value2" multiple copyable text-split="/">
📝 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-base-select ref="selectCopyable" v-model="value2" multiple copyable>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
<p>场景 3:多选设置复制文本分隔符</p>
<tiny-base-select ref="selectCopyable" v-model="value2" multiple copyable text-split="/">
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
<tiny-base-select ref="selectCopyAllTags" v-model="value2" multiple copyable>
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
</tiny-base-select>
<p>场景 3:多选设置复制文本分隔符</p>
<tiny-base-select ref="selectTextSplit" v-model="value2" multiple copyable text-split="/">
<tiny-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </tiny-option>
🤖 Prompt for AI Agents
In examples/sites/demos/mobile-first/app/base-select/copy-multi.vue around lines
8 to 13, both tiny-base-select components use the same ref "selectCopyable",
causing the first ref to be overwritten; change them to unique ref names (for
example "selectCopyableSingle" and "selectCopyableMulti" or similar) and update
any code that accesses these refs accordingly so each component can be
referenced independently.

Comment on lines +52 to +54
options2: [],
value1: '选项 1',
value2: 'Alabama',
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

Initialize value2 consistently with options2.

value2 is set to 'Alabama' at initialization, but options2 is an empty array until the mounted hook completes. This creates a temporary mismatch where the selected value doesn't exist in the options list, which could cause console warnings or unexpected behavior during initial render.

Consider either:

  • Initializing value2 to an empty string: value2: ''
  • Pre-populating options2 with at least the selected item
-      value2: 'Alabama',
+      value2: '',
📝 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
options2: [],
value1: '选项 1',
value2: 'Alabama',
options2: [],
value1: '选项 1',
value2: '',
🤖 Prompt for AI Agents
In examples/sites/demos/mobile-first/app/base-select/copy-single.vue around
lines 52 to 54, value2 is initialized to "Alabama" while options2 is an empty
array until mounted, causing a transient mismatch; either initialize value2 to
an empty string (value2: '') or ensure options2 is pre-populated with the
selected item before render (add the corresponding option object to options2),
so the initial selected value exists in the options list.

Comment on lines +119 to +131
filter(value) {
const select = this.$refs.selectRef
if (value) {
select.state.cachedOptions.forEach((item) => {
item.state.visible = item.label.includes(value)
})
} else {
select.state.cachedOptions.forEach((item) => {
item.state.visible = true
})
}
},
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

🧩 Analysis chain

🌐 Web query:

TinyBaseSelect filter-method API @opentiny/vue documentation

💡 Result:

I couldn't find a published "TinyBaseSelect filter-method" page in the @opentiny/vue docs, but the BaseSelect component (package @opentiny/vue-base-select) source and TypeScript declarations are available (useful for its API). See the package files on UNPKG. (app.unpkg.com)

Would you like me to extract the exact props/types (including any filter-related prop) from the package files?

Citations:


🌐 Web query:

@opentiny/vue TinyBaseSelect public API filtering recommended approach

💡 Result:

Short answer — use the Select's built‑in filtering pattern: keep the full options list in your component/state, and either

  • enable the component's filterable mode (client filtering) and supply a computed/derived filtered options list to (or use the component's built‑in filter callback/slot if provided), or
  • for large/remote data sets, use the component's remote / remote-method pattern (listen to input changes, call your API, then replace the options array).

Why: that keeps the public API surface small (v-model for value + props for options/filterable/remote) and keeps filtering logic in your app (so you can do debouncing, server paging, complex predicates, etc.).

References / examples:

  • tiny-vue repository / component library (installation and Select component in TinyVue). [1]
  • OpenTiny ecosystem package for searchable selects (TinySearchBox) — useful when you need a single, integrated search/filter component. [2]
  • Typical Select filtering pattern (filterable + remote-method) — example from Element Plus docs showing client vs remote filtering and allow-create behavior. Use same approach with TinySelect. [3]

Sources:
[1] https://github.com/opentiny/tiny-vue
[2] https://www.npmjs.com/package/@opentiny/vue-search-box
[3] https://element-plus.org/en-US/component/select-v2

If you want, tell me which TinyVue version you’re using and whether your options are local or remote and I’ll give a short example.


🏁 Script executed:

# Search for TinyBaseSelect component definition and its public API
fd -e vue -e ts -e js | xargs grep -l "TinyBaseSelect\|tiny-base-select" | head -20

Repository: opentiny/tiny-vue

Length of output: 178


🏁 Script executed:

# Look for filter-method or filtering patterns in the codebase
rg "filter.*method|filterMethod" --type vue -A 3 -B 3 | head -100

Repository: opentiny/tiny-vue

Length of output: 178


🏁 Script executed:

# Check if there are other examples using TinyBaseSelect with filtering
fd -type f -name "*.vue" | xargs rg "select\.state\.|state\.visible" 2>/dev/null | head -50

Repository: opentiny/tiny-vue

Length of output: 178


🏁 Script executed:

# Find the file in the current repository
find . -name "copy-single.vue" -type f

Repository: opentiny/tiny-vue

Length of output: 178


🏁 Script executed:

# Examine the full file context
if [ -f "examples/sites/demos/mobile-first/app/base-select/copy-single.vue" ]; then
  wc -l "examples/sites/demos/mobile-first/app/base-select/copy-single.vue"
fi

Repository: opentiny/tiny-vue

Length of output: 178


🏁 Script executed:

# Check if this state manipulation pattern appears elsewhere in the codebase
rg "select\.state\." --type vue -B 2 -A 2 | head -80

Repository: opentiny/tiny-vue

Length of output: 178


🏁 Script executed:

# Look for TinyBaseSelect component definition in this repo
fd -type f \( -name "*.vue" -o -name "*.ts" -o -name "*.js" \) -path "*/base-select*" | head -20

Repository: opentiny/tiny-vue

Length of output: 178


Avoid directly manipulating internal component state.

The filter method accesses and modifies internal component state properties (select.state.cachedOptions, item.state.visible). This tightly couples the demo to the component's internal implementation and may break if the library refactors its internal structure.

The recommended approach is to use the component's public API: either enable filterable mode and manage the full options list in component state (updating which items to display), or use the remote-method pattern for server-side filtering. This keeps filtering logic in your application code and maintains compatibility with library updates.

🤖 Prompt for AI Agents
In examples/sites/demos/mobile-first/app/base-select/copy-single.vue around
lines 119–131, the filter method directly reads and mutates internal properties
(select.state.cachedOptions and item.state.visible); remove that internal-state
manipulation and implement filtering via the component's public API instead —
either enable the select's filterable mode and pass a computed/managed options
array that you update to reflect the filter string, or wire up the component's
remote-method pattern to perform filtering and return the filtered options;
update the method to compute a new options array or call the remote-method and
set the component's bound options prop rather than toggling internal
item.state.visible.

:key="item.value"
:label="item.label"
:value="item.value"
@click.native="clickItem(item.value)"
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Replace deprecated @click.native with standard @click.

The .native modifier is deprecated in Vue 3. For the tiny-option component, use the standard @click event instead.

Apply this diff:

-        @click.native="clickItem(item.value)"
+        @click="clickItem(item.value)"
🤖 Prompt for AI Agents
In examples/sites/demos/mobile-first/app/base-select/memoize-usage.vue around
line 9, the template uses the deprecated @click.native modifier; replace the use
of @click.native="clickItem(item.value)" with the standard
@click="clickItem(item.value)" on the tiny-option component so it uses Vue 3
event handling (remove the .native modifier and keep the same handler).

Comment on lines +196 to +205
demoId: 'show-alloption',
name: {
'zh-CN': '不展示全选',
'en-US': 'Hide Select All'
},
desc: {
'zh-CN': '<p>通过 <code>show-alloption</code> 属性设置多选时不展示 <code>全选</code> 选项,默认展示。</p>\n',
'en-US':
'<p>By setting the <code>show-allocation</code> attribute, do not display the <code>select all</code> option when multiple selections are made, and display by default.</p>\n'
},
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

Fix prop name typo in show-alloption English description

The EN description mentions <code>show-allocation</code>, but the actual prop name used in this demo and code file is show-alloption. This mismatch is likely to confuse users copying from the docs.

-        'en-US':
-          '<p>By setting the <code>show-allocation</code> attribute, do not display the <code>select all</code> option when multiple selections are made, and display by default.</p>\n'
+        'en-US':
+          '<p>By setting the <code>show-alloption</code> attribute, do not display the <code>select all</code> option when multiple selections are made. It is displayed by default.</p>\n'
📝 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
demoId: 'show-alloption',
name: {
'zh-CN': '不展示全选',
'en-US': 'Hide Select All'
},
desc: {
'zh-CN': '<p>通过 <code>show-alloption</code> 属性设置多选时不展示 <code>全选</code> 选项,默认展示。</p>\n',
'en-US':
'<p>By setting the <code>show-allocation</code> attribute, do not display the <code>select all</code> option when multiple selections are made, and display by default.</p>\n'
},
demoId: 'show-alloption',
name: {
'zh-CN': '不展示全选',
'en-US': 'Hide Select All'
},
desc: {
'zh-CN': '<p>通过 <code>show-alloption</code> 属性设置多选时不展示 <code>全选</code> 选项,默认展示。</p>\n',
'en-US':
'<p>By setting the <code>show-alloption</code> attribute, do not display the <code>select all</code> option when multiple selections are made. It is displayed by default.</p>\n'
},
🤖 Prompt for AI Agents
examples/sites/demos/mobile-first/app/base-select/webdoc/base-select.js lines
196-205: the English description incorrectly references
<code>show-allocation</code> instead of the actual prop name
<code>show-alloption</code>; update the EN desc string to use
<code>show-alloption</code> (and keep the surrounding wording referring to the
"select all" option unchanged) so the prop name matches the demo and code.

Comment on lines +397 to +405
demoId: 'memoize-usage',
name: {
'zh-CN': '手动缓存',
'en-US': 'Manual caching'
},
desc: {
'zh-CN': '<p>使用 tiny-option 组件,则需要手动加入缓存功能。</p>\n',
'en-US': '<p>If using the tiny-option component, you need to manually add caching functionality.<p>'
},
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

Close the <p> tag in memoize-usage English description

The EN paragraph ends with <p> instead of </p>, which can lead to malformed HTML in the rendered docs.

-        'en-US': '<p>If using the tiny-option component, you need to manually add caching functionality.<p>'
+        'en-US': '<p>If using the tiny-option component, you need to manually add caching functionality.</p>\n'
🤖 Prompt for AI Agents
In examples/sites/demos/mobile-first/app/base-select/webdoc/base-select.js
around lines 397 to 405, the English description for demoId 'memoize-usage'
opens a paragraph with <p> but mistakenly closes with <p> instead of </p>;
update the 'en-US' desc string to end with a proper closing tag </p> so the HTML
is well-formed.

Comment on lines +447 to +457
demoId: 'slot-prefix',
name: {
'zh-CN': '输入框前缀插槽',
'en-US': 'Predix slot'
},
desc: {
'zh-CN': '<p>通过 <code>prefix</code> 插槽自定义输入框前缀的 HTML 模板。</p>\n',
'en-US': '<p>Customize the HTML template for the input box prefix through the <code>prefix</code> slot. </p>\n'
},
codeFiles: ['slot-prefix.vue']
},
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

Correct “Predix slot” typo in slot-prefix demo name

The EN name currently says “Predix slot”, which looks like a typo. Recommend using “Prefix slot” to match the prop/slot name.

       name: {
         'zh-CN': '输入框前缀插槽',
-        'en-US': 'Predix slot'
+        'en-US': 'Prefix slot'
       },
📝 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
demoId: 'slot-prefix',
name: {
'zh-CN': '输入框前缀插槽',
'en-US': 'Predix slot'
},
desc: {
'zh-CN': '<p>通过 <code>prefix</code> 插槽自定义输入框前缀的 HTML 模板。</p>\n',
'en-US': '<p>Customize the HTML template for the input box prefix through the <code>prefix</code> slot. </p>\n'
},
codeFiles: ['slot-prefix.vue']
},
demoId: 'slot-prefix',
name: {
'zh-CN': '输入框前缀插槽',
'en-US': 'Prefix slot'
},
desc: {
'zh-CN': '<p>通过 <code>prefix</code> 插槽自定义输入框前缀的 HTML 模板。</p>\n',
'en-US': '<p>Customize the HTML template for the input box prefix through the <code>prefix</code> slot. </p>\n'
},
codeFiles: ['slot-prefix.vue']
},
🤖 Prompt for AI Agents
In examples/sites/demos/mobile-first/app/base-select/webdoc/base-select.js
around lines 447 to 457, the English demo name has a typo "Predix slot"; update
the 'en-US' string for the demo name from "Predix slot" to "Prefix slot" so it
matches the prop/slot name and other locales.

Comment on lines +483 to +493
demoId: 'slot-label',
name: {
'zh-CN': '标签插槽',
'en-US': 'Reference slot'
},
desc: {
'zh-CN': '<p>通过 <code>label</code> 插槽自定义多选选中标签的 HTML 模板。</p>\n',
'en-US':
'<p>Customize the HTML template for multiple-choice selected labels through the <code>label</code> slot. </p>'
},
codeFiles: ['slot-label.vue']
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

Fix English name for slot-label demo (currently repeats “Reference slot”)

The slot-label demo’s EN name is “Reference slot”, which duplicates the previous slot-reference demo and doesn’t describe the label/tag slot. Suggest aligning it with the CN name:

       name: {
         'zh-CN': '标签插槽',
-        'en-US': 'Reference slot'
+        'en-US': 'Label slot'
       },
📝 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
demoId: 'slot-label',
name: {
'zh-CN': '标签插槽',
'en-US': 'Reference slot'
},
desc: {
'zh-CN': '<p>通过 <code>label</code> 插槽自定义多选选中标签的 HTML 模板。</p>\n',
'en-US':
'<p>Customize the HTML template for multiple-choice selected labels through the <code>label</code> slot. </p>'
},
codeFiles: ['slot-label.vue']
demoId: 'slot-label',
name: {
'zh-CN': '标签插槽',
'en-US': 'Label slot'
},
desc: {
'zh-CN': '<p>通过 <code>label</code> 插槽自定义多选选中标签的 HTML 模板。</p>\n',
'en-US':
'<p>Customize the HTML template for multiple-choice selected labels through the <code>label</code> slot. </p>'
},
codeFiles: ['slot-label.vue']
🤖 Prompt for AI Agents
In examples/sites/demos/mobile-first/app/base-select/webdoc/base-select.js
around lines 483 to 493, the English name for the demo with demoId 'slot-label'
is incorrect ("Reference slot") and duplicates the previous 'slot-reference'
demo; update the 'en-US' value to a descriptive name matching the Chinese, e.g.
"Label slot" or "Tag slot" (replace 'Reference slot' with 'Label slot') so the
EN name accurately describes the label/tag slot demo.

Comment on lines +577 to +588
id: 'filterable',
name: '可搜索',
support: {
value: true
},
description: '支持输入关键字进行选项搜索。',
cloud: {
value: true
},
apis: ['filterable'],
demos: ['filterable']
}
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 features.filterable.demos reference to non-existent demo ID

In the features section, the filterable feature points to demos: ['filterable'], but there is no demo with demoId: 'filterable' in this file. The relevant demo here is demoId: 'filter-method' (and possibly remote-method).

At minimum, this should be updated so the feature links to an existing demo ID; for example:

      apis: ['filterable'],
-      demos: ['filterable']
+      demos: ['filter-method']

Please confirm whether remote-method should also be included.

📝 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
id: 'filterable',
name: '可搜索',
support: {
value: true
},
description: '支持输入关键字进行选项搜索。',
cloud: {
value: true
},
apis: ['filterable'],
demos: ['filterable']
}
id: 'filterable',
name: '可搜索',
support: {
value: true
},
description: '支持输入关键字进行选项搜索。',
cloud: {
value: true
},
apis: ['filterable'],
demos: ['filter-method']
}
🤖 Prompt for AI Agents
In examples/sites/demos/mobile-first/app/base-select/webdoc/base-select.js
around lines 577 to 588, the features.filterable.demos array incorrectly
references a non-existent demo id 'filterable'; update that array to reference
the actual demo id(s) present in this file (e.g., replace with ['filter-method']
or ['filter-method','remote-method'] if both demos apply), and confirm whether
'remote-method' should be included by checking the demos defined earlier in the
file and adding it if it demonstrates the filterable behavior.

@zzcr zzcr merged commit dba45e3 into opentiny:dev Dec 4, 2025
10 checks passed
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.

2 participants