-
Notifications
You must be signed in to change notification settings - Fork 332
feat(base-select,grid-select): moobile-first base-select and grid-select doc #3872
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughAdds 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
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Areas requiring attention:
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this 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: Missingmobile-firstmode formodelValue / v-modelprop.The
modelValue / v-modelprop still hasmode: ['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: Adddata-tagso the scoped width style applies to this demoThe 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@clearevent handler for consistency.The multi-select instance has the
clearableprop but is missing the@clearevent 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
@clickhandler, 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-defaultare defined in either style block. In contrast, Scene 2 defines.double-rowstyles. 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. Sinceitem.filteris 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
value5to 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: Initializeoptions2to include the default value.
value2is set to'Alabama'butoptions2starts empty. This mismatch may cause console warnings or display issues untilremoteMethodpopulates 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:
remoteMethod4togglesloading4, but the scenario 4<tiny-base-select>(Lines 51–59) never binds:loadingorloading-text, so the user never sees the loading state.- Data defines
loading1–loading5(Lines 116–120) but noloading6.- Line 96: Scenario 6 binds
:loading="loading5", even thoughremoteMethod6(Lines 261–271) never togglesloading5(or any loading flag), so that binding is effectively dead and confusing.loading4andloading5end 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
loading6todata(), bind scenario 4 and 6 selects to their own flags, and toggle those flags inremoteMethod4/remoteMethod6.- Option B (simplify):
- If you don't want loading indicators for scenarios 4 and 6, remove the
loading4toggling inremoteMethod4and 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: InitializecacheValueas a string to match localStorage usage
cacheValueis initialized as an array but later assigned the result oflocalStorage.getItem, which is a string ornull. 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 stylewidth: 280pxon 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: Fixfeatures.filterable.demosto reference the actual demo idThe
filterablefeature 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 inmemoize-usageEN descriptionThe 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 inshow-alloptionEN descriptionThe EN description uses
<code>show-allocation</code>but the actual prop isshow-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: Clarifymultiple-limitvsshow-limit-textsemantics and fix EN wordingThe CN/EN descriptions for
multiple-limitandshow-limit-textin 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
multiplemode but initializesvalueas an empty string. For multi-select,valueshould 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-headselects elements with both classes on the same element. Since.label-user-headis 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 responsivenessLabels 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 demoSince this is under mobile-first demos, a fixed
width: 280pxmay 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 behaviorBoth 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 usingvalue1/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: Initializevalueas an array formultiplemodeFor a multi‑select,
v-modelis typically an array of selected values; initializingvalueas a string can be confusing and may not match the expected type formultiplemode. 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 clarityBoth selects share the same
valueandoptions. It works here (no options), but giving each scenario its ownvalue(and, if needed, its ownoptions) 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 layoutUsing a fixed
width: 280pxworks 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 inremoveTag, the visibility state invisibleChange).Example enhancement:
- change() { + change(value) { TinyModal.message({ - message: '触发 change 事件', + message: `触发 change 事件,新值: ${JSON.stringify(value)}`, status: 'info' }) },
108-111: Remove unusedpselector.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: Initializevalue2as an array for the multiple-select caseFor
multiplemode,v-modelis typically an array of selected values. Herevalue2is 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 infilterMethodandfilterto avoid edge-case runtime errorsIf
filterMethodis called beforetreeRefis set, or if a tree node lacks alabelfield, 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 sharedv-modelacross all selectsAll
tiny-base-selectinstances are bound to the sameformData.select1array, 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 informData(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 />/ where possibleThe layout relies heavily on multiple
<br />tags and<p> </p>for vertical spacing. For readability and easier tuning later, consider moving most of this spacing into CSS (e.g., margins on.custom-formor 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 fixed350pxwidth for mobile-first demo
.demo-boxis constrained to a fixedwidth: 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 demoTwo small suggestions for the demo clarity:
v-forkey:
:key="index"works but is not ideal; a stable key like the option id avoids potential update pitfalls and better reflects best practice.- Displaying
value:
valueis 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 globalwindownamespace
window.gridSelectRadioBigData = data.lengthis 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.lengthThis keeps globals grouped while preserving the ability to inspect the value from outside.
42-45: Make container width more responsive for mobile-first layoutFor a “mobile-first” demo, a fixed
width: 350pxcan 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
dataarrays ingridOpSingleandgridOpMultiare 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 duplicaterefand shared model between different demo scenesBoth Scene 2 and Scene 3 use the same
ref="selectCopyable"and the samev-model="value2". While this works, it makes$refs.selectCopyablean 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
$refsat all, another option is simply to drop bothrefattributes.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
224pxand option height54pxappear 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
remoteMethod1–remoteMethod5are 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 !== undefinedto something likequery && 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: SynccacheValueon mount for a more consistent demo state
cacheValueis only updated insidecacheChange, so ifTinyBaseSelectrestores a cached value on mount viacache-op, the select and the displayed cache text can be out of sync until the user changes the value again. CallingcacheChangeonce 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 literalThe string
'test456'is used both in theMemorizeconstructor 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 unnecessaryautocompleteattribute.The
autocompleteattribute 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 purposeTwo slot demos have inconsistent EN names:
- Line 450:
'Predix slot'is likely a typo for “Prefix slot”.- Line 486: EN name for
slot-labelis'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 detailsThe 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: AvoidJSON.parseinbuildOptionsfor 100k itemsUsing
JSON.parseinside theArray.frommap 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: OPTIONSexamples/sites/demos/mobile-first/app/base-select/basic-usage.vue (1)
1-47: Basic usage demo is clear; optional small optimization for iconsThe 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.dropis globalThe select configuration and data look good, and using
popper-class="drop"matches the global.dropstyle.Note that the second
<style>block is unscoped, so.dropwill 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 reusedrop.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 refsThe
initQueryandremoteMethodimplementations are consistent and make sense for a large remote dataset, and the grid configs look correct.Two small cleanups you might consider:
- Both
<tiny-grid-select>elements useref="select", but$refs.selectis 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" ...
- Since
created()immediately overwritesallData, you can initialize it directly there and drop theallData: []fromdata()for slightly clearer intent, or vice versa (build it indata()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选项 4to选项 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
valueparameter inloadChildren(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
📒 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.vueexamples/sites/demos/mobile-first/app/base-select/is-drop-inherit-width.vueexamples/sites/demos/mobile-first/app/base-select/filter-method.vueexamples/sites/demos/mobile-first/app/base-select/disabled.vueexamples/sites/demos/mobile-first/app/base-select/hide-drop.vueexamples/sites/demos/mobile-first/app/base-select/collapse-tags.vueexamples/sites/demos/mobile-first/app/base-select/show-alloption.vueexamples/sites/demos/mobile-first/app/base-select/tag-type.vueexamples/sites/demos/mobile-first/app/base-select/optimization.vueexamples/sites/demos/mobile-first/app/base-select/memoize-usage.vueexamples/sites/demos/mobile-first/app/base-select/events.vueexamples/sites/demos/mobile-first/app/base-select/clearable.vueexamples/sites/demos/mobile-first/app/base-select/native-properties.vueexamples/sites/demos/mobile-first/app/base-select/show-tip.vueexamples/sites/demos/mobile-first/app/base-select/popup-style-position.vueexamples/sites/demos/mobile-first/app/base-select/slot-label.vueexamples/sites/demos/mobile-first/app/base-select/slot-footer.vueexamples/sites/demos/mobile-first/app/base-select/basic-usage.vueexamples/sites/demos/mobile-first/app/base-select/multiple.vueexamples/sites/demos/mobile-first/app/base-select/no-data-text.vueexamples/sites/demos/mobile-first/app/base-select/slot-reference.vueexamples/sites/demos/mobile-first/app/base-select/slot-panel.vueexamples/sites/demos/mobile-first/app/base-select/cache-usage.vueexamples/sites/demos/mobile-first/app/base-select/size.vueexamples/sites/demos/mobile-first/app/base-select/slot-default.vueexamples/sites/demos/mobile-first/app/base-select/allow-create.vueexamples/sites/demos/mobile-first/app/base-select/binding-obj.vueexamples/sites/demos/mobile-first/app/base-select/clear-no-match-value.vueexamples/sites/demos/mobile-first/app/grid-select/config.vueexamples/sites/demos/mobile-first/app/base-select/option-group.vueexamples/sites/demos/mobile-first/app/base-select/slot-prefix.vueexamples/sites/demos/mobile-first/app/base-select/filter-mode.vueexamples/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)
| 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 | ||
| }) | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.filterinstead ofitem.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" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 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 2Repository: 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.
| value1: [], | ||
| value2: '', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix the v-model type mismatches.
The data initialization types don't match their usage patterns:
value1is initialized as an array but used for single-select (line 19), which expects a string or number.value2is 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.
| 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.
| <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> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 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
doneRepository: 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.
| <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> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| <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.
examples/sites/demos/pc/app/grid-select/basic-usage-composition-api.vue
Outdated
Show resolved
Hide resolved
9f26573 to
c070798
Compare
There was a problem hiding this 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 desiredOverall the example is clear and correctly wires
tiny-base-select/tiny-optionwith theis-drop-inherit-widthprop and scoped width styling. The only thing to double‑check is that both selects bind to the samevaluemodel, 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 likevalueScene1/valueScene2.examples/docs/newsrc/utils/componentsDoc.js (2)
4-5: Consider simplifying the redundant return.Returning
'grid-select'whenpath === 'grid-select'is redundant. While it makes the intent explicit (preventing 'grid-select' from matching thestartsWith('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
getPathfunction 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: []plusgridOpMulticonfig are consistent with a multi-select scenario and mirrorgridOpSinglewell.- In this file, the multi-select column uses
type: 'selection', while the mobile-first demo usestype: 'checkbox'for the same scenario. It would be good to confirm which value is the canonical one forTinyGridSelectmulti-select columns and keep both demos in sync.Also,
gridOpSingle.dataandgridOpMulti.dataare 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 columntypeand keep PC / mobile demos consistentHere the multi-select grid uses
columns: [{ type: 'checkbox', ... }], while the PC demo’s multi-select grid usestype: 'selection'. To avoid confusing users reading both docs, it would be good to:
- Confirm which column
typeis officially recommended forTinyGridSelectmulti-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 containerUsing a fixed
width: 280pxon#basic-usageis 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
remoteMethodimplementations share nearly identical logic: check if query is defined, set a loading flag, simulate async fetch withsetTimeout, filterthis.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
buildOptionsfunction usesJSON.parseunnecessarily. 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
value1andvalue2are initialized with selected values, but scenarios 2 and 3 (lines 8 and 12) share the samevalue2model. 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 forfilterable/filter-method/no-match-textThe 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 inoptimizationEnglish descriptionThe 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
📒 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.vueexamples/sites/demos/mobile-first/app/base-select/binding-obj.vueexamples/sites/demos/mobile-first/app/base-select/memoize-usage.vueexamples/sites/demos/mobile-first/app/base-select/is-drop-inherit-width.vueexamples/sites/demos/mobile-first/app/base-select/slot-default.vueexamples/sites/demos/mobile-first/app/base-select/optimization.vueexamples/sites/demos/mobile-first/app/base-select/copy-single.vueexamples/sites/demos/mobile-first/app/base-select/native-properties.vueexamples/sites/demos/mobile-first/app/base-select/clear-no-match-value.vueexamples/sites/demos/mobile-first/app/base-select/slot-prefix.vueexamples/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
filterMethodcorrectly delegates to the tree's filter method via ref, and thefiltercallback 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 correctThe two scenes are clearly labeled and the second
tiny-grid-selectis correctly bound to its ownv-modeland 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 clearThe two scenes (single and multi-select) are well separated and both
tiny-grid-selectinstances are correctly bound (valuevsvalue2,gridOpSinglevsgridOpMulti), 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 solidThe two scenes clearly show single and multi-select behavior:
valandmultiValare initialized with non-matching entries, and theoptionsvalues 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-tagattribute 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 theautocompleteattribute handling in TinyBaseSelect.The
autocompleteattribute is passed as a boolean prop on line 2. In standard HTML,autocompleteshould 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 acceptsautocompleteas a boolean and how it renders to the DOM, or useautocomplete="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-fieldandtext-fieldto 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-tagvariant. 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-forloop conditionally wraps options inTinyTooltipor renders them directly, but both branches use:key="item.value"on different component types. Whenitem.tipexists, the key is onTinyTooltip; otherwise, it's onTinyOption. 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> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| 场景 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.
| <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> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| <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.
| options2: [], | ||
| value1: '选项 1', | ||
| value2: 'Alabama', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
value2to an empty string:value2: '' - Pre-populating
options2with 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.
| 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.
| 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 | ||
| }) | ||
| } | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 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 -20Repository: 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 -100Repository: 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 -50Repository: opentiny/tiny-vue
Length of output: 178
🏁 Script executed:
# Find the file in the current repository
find . -name "copy-single.vue" -type fRepository: 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"
fiRepository: 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 -80Repository: 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 -20Repository: 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)" |
There was a problem hiding this comment.
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).
| 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' | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| 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.
| 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>' | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| 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'] | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| 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.
| 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'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| 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.
| id: 'filterable', | ||
| name: '可搜索', | ||
| support: { | ||
| value: true | ||
| }, | ||
| description: '支持输入关键字进行选项搜索。', | ||
| cloud: { | ||
| value: true | ||
| }, | ||
| apis: ['filterable'], | ||
| demos: ['filterable'] | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| 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.
PR
feat:多端base-select以及grid-select文档
PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
What is the current behavior?
Issue Number: N/A
What is the new behavior?
Does this PR introduce a breaking change?
Other information
Summary by CodeRabbit
New Features
Documentation
Chores
✏️ Tip: You can customize this high-level summary in your review settings.