docs(sites) update docs and apis (#1070)

This commit is contained in:
ajaxzheng 2023-12-08 18:20:12 +08:00 committed by GitHub
parent 6cea1e6316
commit 268d84fc90
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
313 changed files with 16591 additions and 1746 deletions

1
.gitignore vendored
View File

@ -59,3 +59,4 @@ packages/theme/scripts/themeExcel.xlsx
packages/theme/src/theme/*-theme/component.js
pnpm-lock.yaml
gulp/bundle.json

34
count-api.js Normal file
View File

@ -0,0 +1,34 @@
const fs = require('fs');
const basePath = './examples/sites/demos/pc/app';
const readFile = function (path) {
let componentCount = 0;
let apiCount = 0;
const readDir = fs.readdirSync(path);
readDir.forEach(i => {
const curDir = `${path}/${i}`;
const stat = fs.statSync(curDir);
if (stat.isFile() && i.endsWith('.js')) {
componentCount += 1;
const data = fs.readFileSync(curDir, 'utf-8');
let dataJson = null;
try {
dataJson = JSON.parse(data);
} catch (err) {
console.log('err:', err);
}
if (dataJson !== null) {
apiCount += (dataJson.attrs?.length || 0) + (dataJson.slots?.length || 0) + (dataJson.events?.length || 0) + (dataJson.methods?.length || 0);
}
}
});
console.log('componentCount:', componentCount);
console.log('apiCount:', apiCount);
}
readFile(basePath);

View File

@ -1,16 +1,15 @@
export default {
column: '2',
owner: '',
demos: [
{
demos: [{
demoId: 'type',
name: {
'zh-CN': '类型',
'en-US': 'basic usage'
'en-US': 'type'
},
desc: {
'zh-CN': '<p>通过<code>type</code>设置不同的类型。可选值success、warning、info、error默认值info 。</p>',
'en-US': '<p>button type</p>'
'en-US': '<p>Use <code>type</code> to set different types. The options are success, warning, info, and error. The default value is info.</p>'
},
codeFiles: ['type.vue']
},
@ -18,11 +17,11 @@ export default {
demoId: 'size',
name: {
'zh-CN': '大尺寸',
'en-US': 'button round'
'en-US': 'Large size'
},
desc: {
'zh-CN': '<p>通过 <code>size</code> 属性设置不同的尺寸可选值nomal、large默认值nomal 。</p>',
'en-US': '<p>button round</p>'
'en-US': '<p>Use the <code>size</code> attribute to set different sizes. The options are nomal and large. The default value is nomal.</p>'
},
codeFiles: ['size.vue']
},
@ -30,12 +29,11 @@ export default {
demoId: 'title',
name: {
'zh-CN': '自定义标题',
'en-US': 'events'
'en-US': 'Custom Title'
},
desc: {
'zh-CN':
'<p>当 <code>size</code>为 large 时显示标题,可设置 <code>title</code> 或 <code>slot</code> 自定义标题。默认标题根据设置的 <code>type</code> 显示。<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>当 <code>size</code>为 large 时显示标题,可设置 <code>title</code> 或 <code>slot</code> 自定义标题。默认标题根据设置的 <code>type</code> 显示。</p>',
'en-US': '<p>When <code>size</code> is set to large, the title is displayed. You can set <code>title</code> or <code>slot</code> to customize the title. The default title is displayed according to the set <code>type</code>.</p>'
},
codeFiles: ['title.vue']
},
@ -55,11 +53,11 @@ export default {
demoId: 'closable',
name: {
'zh-CN': '不可关闭',
'en-US': 'events'
'en-US': 'Can not be closed'
},
desc: {
'zh-CN': '<p>通过 <code>closable</code> 属性可设置是否显示关闭按钮,没有关闭按钮,警告框将不可关闭。<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>通过 <code>closable</code> 属性可设置是否显示关闭按钮,没有关闭按钮,警告框将不可关闭。</p>',
'en-US': '<p>The <code>closable</code> attribute can be used to set whether to display the Close button. If there is no Close button, the Warning dialog box cannot be closed.</p>'
},
codeFiles: ['closable.vue']
},
@ -67,11 +65,11 @@ export default {
demoId: 'custom-description',
name: {
'zh-CN': '自定义提示内容',
'en-US': 'events'
'en-US': 'Customized prompt content'
},
desc: {
'zh-CN': '<p>可通过 <code>description</code> 属性或插槽设置自定义提示内容。<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>可通过 <code>description</code> 属性或插槽设置自定义提示内容。</p>',
'en-US': '<p>You can customize the prompt content through the <code>description</code> property or slot.</p>'
},
codeFiles: ['custom-description.vue']
},
@ -79,11 +77,11 @@ export default {
demoId: 'slot-default',
name: {
'zh-CN': '自定义交互操作',
'en-US': 'events'
'en-US': 'Customizing Interactions'
},
desc: {
'zh-CN': '<p>当 <code>size</code> 为 large 时,设置默认插槽自定义交互操作。<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>当 <code>size</code> 为 large 时,设置默认插槽自定义交互操作。</p>',
'en-US': '<p>Set the default slot custom interaction when <code>size</code> is large.</p>'
},
codeFiles: ['slot-default.vue']
},
@ -91,11 +89,11 @@ export default {
demoId: 'close',
name: {
'zh-CN': '关闭事件',
'en-US': 'events'
'en-US': 'Close Event'
},
desc: {
'zh-CN': '<p><code>close</code> 事件,关闭警告框时触发。<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p><code>close</code> 事件,关闭警告框时触发。</p>',
'en-US': '<p><code>close</code> event, triggered when the warning dialog box is closed.</p>'
},
codeFiles: ['close.vue']
},
@ -103,12 +101,11 @@ export default {
demoId: 'feedback-of-result',
name: {
'zh-CN': '表单提交结果反馈',
'en-US': 'events'
'en-US': 'Form submission result feedback'
},
desc: {
'zh-CN':
'<p>当 <code>size</code> 为 large 时,属性 <code>description</code> 和默认插槽结合使用,可渲染提交反馈界面。<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>当 <code>size</code> 为 large 时,属性 <code>description</code> 和默认插槽结合使用,可渲染提交反馈界面。</p>',
'en-US': '<p>When <code>size</code> is set to large, the <code>description</code> attribute is used together with the default slot to render the submission feedback interface.</p>'
},
codeFiles: ['feedback-of-result.vue']
},
@ -116,11 +113,11 @@ export default {
demoId: 'show-icon',
name: {
'zh-CN': '是否显示图标',
'en-US': 'events'
'en-US': 'Indicates whether to display the icon.'
},
desc: {
'zh-CN': '<p>通过配置 <code>show-icon</code> 属性,控制图标是否显示。<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>通过配置 <code>show-icon</code> 属性,控制图标是否显示。</p>',
'en-US': '<p>You can set the <code>show-icon</code> attribute to control whether to display the icon.</p>'
},
codeFiles: ['show-icon.vue']
},
@ -128,12 +125,11 @@ export default {
demoId: 'show-foldable',
name: {
'zh-CN': '带标题可折叠样式',
'en-US': 'events'
'en-US': 'Collapsible Style with Title'
},
desc: {
'zh-CN':
'<p>通过 `flex-basis` 属性可以设置内容插槽的宽度flex-basis 类型为数组,最多能传入 4 个值,支持百分比,固定宽度及固有的尺寸关键词,默认为 auto详情见 flex 的 flex-basis 属性。<br /> 通过设置`flex-grow`属性可以设置每一项在 flex 容器中分配剩余空间的相对比例,默认为 1。如果不想自动撑满主容器可以设为 0详情见 flex 的 flex-grow 属性。<br />flex-grow 举例:`:flex-grow="[0, 0]" :flex-grow="[2, 1]" :flex-grow="[2, 1,1,1]"` <br />flex-basis 举例:`:flex-basis="["200px", "100px","300px"]" :flex-basis="["75%", "25%"]" :flex-basis="["40%", "20%", "20%", "20%"]"`<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>通过 `flex-basis` 属性可以设置内容插槽的宽度flex-basis 类型为数组,最多能传入 4 个值,支持百分比,固定宽度及固有的尺寸关键词,默认为 auto详情见 flex 的 flex-basis 属性。<br /> 通过设置`flex-grow`属性可以设置每一项在 flex 容器中分配剩余空间的相对比例,默认为 1。如果不想自动撑满主容器可以设为 0详情见 flex 的 flex-grow 属性。<br />flex-grow 举例:`:flex-grow="[0, 0]" :flex-grow="[2, 1]" :flex-grow="[2, 1,1,1]"` <br />flex-basis 举例:`:flex-basis="["200px", "100px","300px"]" :flex-basis="["75%", "25%"]" :flex-basis="["40%", "20%", "20%", "20%"]"`</p>',
'en-US': '<p>The `flex-basis` attribute can be used to set the width of the content slot. The flex-basis type is an array. A maximum of four values can be transferred. The percentage, fixed width, and inherent size keywords are supported. The default value is auto. For details, see the flex-basis attribute of Flex. <br />You can set the relative proportion of the remaining space allocated to each item in the flex container by setting the `flex-grow` attribute. The default value is 1. If you do not want to automatically fill the main container, set this parameter to 0. For details, see the flex-grow attribute of flex. <br />Flex-grow Example: `:flex-grow="[0, 0]" :flex-grow="[2, 1]" :flex-grow="[2, 1,1,1]"` <br />flex-basis Example: `:flex-basis="["200px", "100px","300px"]" :flex-basis="["75%", "25%"]" :flex-basis="["40%", "20%", "20%", "20%"]"`</p>'
},
codeFiles: ['show-foldable.vue']
},
@ -141,7 +137,7 @@ export default {
demoId: 'custom-class',
name: {
'zh-CN': '自定义类名',
'en-US': 'Custom class'
'en-US': 'User-defined class name'
},
desc: {
'zh-CN': '<p>通过<code>custom-class</code>属性设置自定义类名<p>',
@ -150,5 +146,50 @@ export default {
codeFiles: ['custom-class.vue']
}
],
apis: []
}
apis: [{
'name': 'Alert',
'type': 'component',
'props': [{
'name': 'scrolling',
'type': 'String',
'defaultValue': '',
'desc': {
'zh-CN': '是否开启描述文字在鼠标 hover 时滚动显示的动画。',
'en-US': 'Indicates whether to enable the animation of the description text scrolling when the mouse hovers.'
},
'demoId': ''
},
{
'name': 'show-foldable',
'type': 'String',
'defaultValue': '',
'desc': {
'zh-CN': '展示带标题可折叠样式。',
'en-US': 'Shows collapsible styles with titles.'
},
'demoId': ''
},
{
'name': 'single-line',
'type': 'String',
'defaultValue': '',
'desc': {
'zh-CN': '描述内容是否一行显示,超出显示...,默认值为 false。',
'en-US': 'Indicates whether the description is displayed in one line. The default value is false.'
},
'demoId': ''
}
],
'events': [{
'name': 'handleHeaderClick',
'type': 'Function()',
'defaultValue': '',
'desc': {
'zh-CN': '标题点击事件,设置 show-foldable 为 true 时有效。',
'en-US': 'Title click event. This parameter is valid only when show-foldable is set to true.'
},
'demoId': ''
}],
'slots': []
}]
}

View File

@ -9,7 +9,7 @@ export default {
'en-US': 'Basic Usage'
},
desc: {
'zh-CN': '<p>基本用法<p>',
'zh-CN': '<p>基本用法</p>',
'en-US': '<p>Basic Usage</p>'
},
codeFiles: ['basic-usage.vue']
@ -22,9 +22,9 @@ export default {
},
desc: {
'zh-CN':
'<p>通过 <code>:node-config="{ lazy: true, load:() => {...} }"<code>load</code> 设置属性 <code>lazy: true<code>load</code> 和 <code>load</code> 数据加载方法,开启异步加载。<p>',
'<p>通过 <code>:node-config="{ lazy: true, load:() => {...} }"<code>load</code> 设置属性 <code>lazy: true<code>load</code> 和 <code>load</code> 数据加载方法,开启异步加载。</p>',
'en-US':
'<p><p>Set the <code>lazy: true<code>load</code> attribute and <code>load</code>data loading method through <code>:node-config="{lazy: true, load:() => {...}}"<code>load</code> to enable asynchronous loading.<p></p>'
'<p><p>Set the <code>lazy: true<code>load</code> attribute and <code>load</code>data loading method through <code>:node-config="{lazy: true, load:() => {...}}"<code>load</code> to enable asynchronous loading.<p></p>'
},
codeFiles: ['lazyload.vue']
},
@ -36,9 +36,9 @@ export default {
},
desc: {
'zh-CN':
'<p>通过 <code>:node-config="{ checkStrictly: true }"</code> 设置属性 <code>checkStrictly: true</code>,开启父子层级互不关联,可选择非叶子节点,默认值为 <code>false</code> 显示到叶子节点。<p>',
'<p>通过 <code>:node-config="{ checkStrictly: true }"</code> 设置属性 <code>checkStrictly: true</code>,开启父子层级互不关联,可选择非叶子节点,默认值为 <code>false</code> 显示到叶子节点。</p>',
'en-US':
'<p>You can set the <code>checkStrictly: true</code> attribute in <code>:node-config="{checkStrictly: true}"</code> to enable the disassociation between parent and child levels. You can select non-leaf nodes. The default value is <code>false</code>.<p>'
'<p>You can set the <code>checkStrictly: true</code> attribute in <code>:node-config="{checkStrictly: true}"</code> to enable the disassociation between parent and child levels. You can select non-leaf nodes. The default value is <code>false</code>.</p>'
},
codeFiles: ['check-strictly.vue']
},
@ -49,9 +49,9 @@ export default {
'en-US': 'Disable option'
},
desc: {
'zh-CN': '<p>数据源里面带 <code>disabled: true</code> 渲染时自动禁用选项。<p>',
'zh-CN': '<p>数据源里面带 <code>disabled: true</code> 渲染时自动禁用选项。</p>',
'en-US':
'<p>The <code>disabled: true</code> option is automatically disabled during rendering in the data source.<p>'
'<p>The <code>disabled: true</code> option is automatically disabled during rendering in the data source.</p>'
},
codeFiles: ['disabled.vue']
},
@ -63,12 +63,251 @@ export default {
},
desc: {
'zh-CN':
'<p>通过设置 <code>emit-path</code> 属性值为 <code>false</code> 不显示值路径,默认值为 <code>true</code> 显示值路径。<p>',
'<p>通过设置 <code>emit-path</code> 属性值为 <code>false</code> 不显示值路径,默认值为 <code>true</code> 显示值路径。</p>',
'en-US':
'<p>The value path is not displayed by setting the <code>emit-path</code> attribute to <code>false</code>. The default value is <code>true</code>.<p>'
'<p>The value path is not displayed by setting the <code>emit-path</code> attribute to <code>false</code>. The default value is <code>true</code>.</p>'
},
codeFiles: ['emit-path.vue']
}
],
apis: []
apis: [
{
'name': 'CalendarView',
'type': 'component',
'props': [
{
'name': 'day-times',
'type': 'Array',
'defaultValue': '',
'desc': {
'zh-CN': '配置时间线模式下所展示的时间范围,默认为[8,18],可配范围[0,23]。',
'en-US': 'Time range displayed in timeline mode. The default value range is [8, 18]. The value range is [0, 23].'
},
'demoId': ''
},
{
'name': 'disabled ',
'type': 'Function',
'defaultValue': '',
'desc': {
'zh-CN': '日期禁用',
'en-US': 'Date Disabled'
},
'demoId': 'disabled'
},
{
'name': 'events',
'type': 'Array',
'defaultValue': '',
'desc': {
'zh-CN': '日程事件',
'en-US': 'Scheduled Events'
},
'demoId': ''
},
{
'name': 'height',
'type': 'String',
'defaultValue': '',
'desc': {
'zh-CN': '日历高度',
'en-US': 'Calendar height'
},
'demoId': ''
},
{
'name': 'mark-color',
'type': 'String',
'defaultValue': '',
'desc': {
'zh-CN': '点标记的颜色',
'en-US': 'Color of the dot marker'
},
'demoId': ''
},
{
'name': 'mode',
'type': 'String',
'defaultValue': '',
'desc': {
'zh-CN': '显示模式,可选值有 timeline-时间线模式、schedule-日程模式、month-月模式,默认为月模式。',
'en-US': 'Display mode. The options are timeline-timeline, schedule-schedule, and month-month. The default value is month.'
},
'demoId': ''
},
{
'name': 'modes',
'type': 'Array',
'defaultValue': '',
'desc': {
'zh-CN': '模式组,显示模式任意组合',
'en-US': 'Pattern group, any combination of display patterns'
},
'demoId': ''
},
{
'name': 'month',
'type': 'String',
'defaultValue': '',
'desc': {
'zh-CN': '日历当前显示月份',
'en-US': 'The calendar currently displays the month'
},
'demoId': ''
},
{
'name': 'multi-select',
'type': 'Boolean',
'defaultValue': '',
'desc': {
'zh-CN': '日期多选',
'en-US': 'Multiple Dates'
},
'demoId': ''
},
{
'name': 'set-day-bg-color',
'type': 'Function',
'defaultValue': '',
'desc': {
'zh-CN': '设置日期背景色',
'en-US': 'Set Date Background Color'
},
'demoId': ''
},
{
'name': 'show-mark',
'type': 'Function',
'defaultValue': '',
'desc': {
'zh-CN': '显示点标记',
'en-US': 'Show Point Markers'
},
'demoId': ''
},
{
'name': 'show-new-schedule',
'type': 'Function',
'defaultValue': '',
'desc': {
'zh-CN': '显示新增日程按钮',
'en-US': 'Show the button for adding a schedule'
},
'demoId': ''
},
{
'name': 'year',
'type': 'Number',
'defaultValue': '',
'desc': {
'zh-CN': '日历当前显示年份',
'en-US': 'Calendar Current Display Year'
},
'demoId': ''
},
],
'events': [
{
'name': 'month-change',
'type': 'Function()',
'defaultValue': '',
'desc': {
'zh-CN': '月改变事件',
'en-US': 'Month Change Event'
},
'demoId': ''
},
{
'name': 'new-schedule',
'type': 'Function()',
'defaultValue': '',
'desc': {
'zh-CN': '新增日程按钮点击事件',
'en-US': 'Event for adding a schedule button.'
},
'demoId': ''
},
{
'name': 'next-week-click',
'type': 'Function()',
'defaultValue': '',
'desc': {
'zh-CN': '下一周按钮点击事件',
'en-US': 'Next week button click event'
},
'demoId': ''
},
{
'name': 'prev-week-click',
'type': 'Function()',
'defaultValue': '',
'desc': {
'zh-CN': '上一周按钮点击事件',
'en-US': 'Button click event of the previous week'
},
'demoId': ''
},
{
'name': 'selected-date-change',
'type': 'Function()',
'defaultValue': '',
'desc': {
'zh-CN': '选中日期改变事件',
'en-US': 'Select Date Change Event'
},
'demoId': ''
},
{
'name': 'week-change',
'type': 'Function()',
'defaultValue': '',
'desc': {
'zh-CN': '周改变事件',
'en-US': 'Week Change Event'
},
'demoId': ''
},
{
'name': 'year-change',
'type': 'Function()',
'defaultValue': '',
'desc': {
'zh-CN': '年改变事件',
'en-US': 'Year Change Event'
},
'demoId': ''
},
],
'slot': [
{
'name': 'header',
'type': '',
'defaultValue': '',
'desc': { 'zh-CN': '头部插槽', 'en-US': 'Head slot' },
'demoId': ''
},
{
'name': 'timeline',
'type': '',
'defaultValue': '',
'desc': { 'zh-CN': '时间线插槽有timeline1-timeline7 7个插槽', 'en-US': 'Timeline slots, with 7 slots timeline1-timeline7' },
'demoId': ''
},
{
'name': 'tool',
'type': '',
'defaultValue': '',
'desc': { 'zh-CN': '工具栏插槽', 'en-US': 'Toolbar Slot' },
'demoId': ''
},
{
'name': 'weekday',
'type': '',
'defaultValue': '',
'desc': { 'zh-CN': '日程插槽有weekday1-weekday7 7个插槽', 'en-US': 'Schedule slots, with 7 slots weekday1-weekday7' },
'demoId': ''
}
]
}
]
}

View File

@ -1,16 +1,15 @@
export default {
column: '2',
owner: '',
demos: [
{
demos: [{
demoId: 'message',
name: {
'zh-CN': '基本用法',
'en-US': 'events'
'en-US': 'Basic Usage'
},
desc: {
'zh-CN': '<p><p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p></p>',
'en-US': '<p></p>'
},
codeFiles: ['message.vue']
},
@ -18,12 +17,11 @@ export default {
demoId: 'page-empty',
name: {
'zh-CN': '页面级空态',
'en-US': 'events'
'en-US': 'Page-level void'
},
desc: {
'zh-CN':
'<p>通过添加`page-empty`属性展示页面级空态,其中 type 类型有`pagenoperm`、 `pageweaknet`、 `pagenothing`、 `pageservererror`<br> 对应场景:<br>`pagenoperm` :无访问权限<br>`pageweaknet` :网络异常<br>`pagenothing` :你访问的页面不存在<br>`pageservererror`:服务器异常 <p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>通过添加`page-empty`属性展示页面级空态,其中 type 类型有`pagenoperm`、 `pageweaknet`、 `pagenothing`、 `pageservererror`<br> 对应场景:<br>`pagenoperm` :无访问权限<br>`pageweaknet` :网络异常<br>`pagenothing` :你访问的页面不存在<br>`pageservererror`:服务器异常 </p>',
'en-US': '<p>The page-level empty state is displayed by adding the `page-empty` attribute. The type types include `pagenoperm`, `pageweaknet`, `pagenothing`, and `pageservererror`.<br>Scenario:<br>`pagenoperm`: no access permission<br>`pageweaknet`: network exception<br>`pagenothing`: The page you access does not exist<br>`pageservererror`: The server is abnormal</p>'
},
codeFiles: ['page-empty.vue']
},
@ -31,12 +29,11 @@ export default {
demoId: 'component-empty',
name: {
'zh-CN': '组件级空态',
'en-US': 'events'
'en-US': 'Component-level empty state'
},
desc: {
'zh-CN':
'<p>通过添加`component-empty`属性展示组件级空态,其中 type 类型有`noperm、 nodata、 weaknet、noresult、 nonews`<br> 对应场景:<br>`noperm` :无访问权限<br>`nodata` :暂无数据<br>`weaknet` :网络不给力<br>`noresult`:无相关搜索结果<br>`nonews`:暂无最新消息<br><p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>通过添加`component-empty`属性展示组件级空态,其中 type 类型有`noperm、 nodata、 weaknet、noresult、 nonews`<br> 对应场景:<br>`noperm` :无访问权限<br>`nodata` :暂无数据<br>`weaknet` :网络不给力<br>`noresult`:无相关搜索结果<br>`nonews`:暂无最新消息<br></p>',
'en-US': '<p>Add the `component-empty` attribute to display the component-level empty state. The type type can be `noperm, nodata, weaknet, noresult, or nonews`<br>The corresponding scenario is as follows: <br>`noperm`: No access<br>`nodata`: no data<br>`weaknet`: network is not powerful<br>`noresult`: no related search results<br>`nonews`: no latest news<br></p>'
},
codeFiles: ['component-empty.vue']
},
@ -44,11 +41,11 @@ export default {
demoId: 'sub-message',
name: {
'zh-CN': '自定义二级标题内容',
'en-US': 'events'
'en-US': 'User-defined level-2 title content'
},
desc: {
'zh-CN': '<p>通过`sub-message`自定义二级标题<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>通过`sub-message`自定义二级标题</p>',
'en-US': '<p>Customizing Level-2 Titles Using `sub-message`</p>'
},
codeFiles: ['sub-message.vue']
},
@ -59,8 +56,8 @@ export default {
'en-US': 'button-text'
},
desc: {
'zh-CN': '<p>已去除`button-text`自定义按钮文本,直接可以通过插槽自定义<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>已去除`button-text`自定义按钮文本,直接可以通过插槽自定义</p>',
'en-US': '<p>Customizing Level-2 Titles Using `sub-message`</p>'
},
codeFiles: ['button-text.vue']
},
@ -71,11 +68,86 @@ export default {
'en-US': 'content-slot'
},
desc: {
'zh-CN': '<p>通过命名插槽 `content`,自定义内容区<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>通过命名插槽 `content`,自定义内容区</p>',
'en-US': '<p>Customize the content area by naming the slot `content`</p>'
},
codeFiles: ['content-slot.vue']
}
],
apis: []
}
apis: [{
'name': 'Exception',
'type': 'component',
'props': [{
'name': 'component-page',
'type': 'Boolean',
'defaultValue': '',
'desc': {
'zh-CN': '设置组件级空态',
'en-US': 'Set component-level empty state'
},
'demoId': 'component-empty'
},
{
'name': 'exception-class',
'type': 'String',
'defaultValue': '',
'desc': {
'zh-CN': '设置自定义类',
'en-US': 'Setting Custom Classes'
},
'demoId': ''
},
{
'name': 'page-empty ',
'type': 'Boolean',
'defaultValue': '',
'desc': {
'zh-CN': '设置页面级空态',
'en-US': 'Set page-level empty status'
},
'demoId': 'page-empty'
},
{
'name': 'sub-message',
'type': 'String',
'defaultValue': '',
'desc': {
'zh-CN': '设置二级标题',
'en-US': 'Set Level-2 Title'
},
'demoId': 'sub-message'
},
{
'name': 'type',
'type': 'String',
'defaultValue': '',
'desc': {
'zh-CN': '设置页面级空态类型。默认值为nodata',
'en-US': 'Sets the page-level empty state type. The default value is nodata.'
},
'demoId': 'page-empty'
}
],
'slots': [{
'name': 'content',
'type': '',
'defaultValue': '',
'desc': {
'zh-CN': '内容插槽。可以设置自定义展示内容',
'en-US': 'Content slot. Custom display content can be set.'
},
'demoId': 'content-slot'
},
{
'name': 'default',
'type': '',
'defaultValue': '',
'desc': {
'zh-CN': '默认插槽',
'en-US': 'Default Slot'
},
'demoId': ''
}
]
}]
}

View File

@ -1,16 +1,15 @@
export default {
column: '2',
owner: '',
demos: [
{
demos: [{
demoId: 'basic-usage',
name: {
'zh-CN': '垂直图形',
'en-US': 'events'
'en-US': 'Vertical Graphics'
},
desc: {
'zh-CN': '<p><p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>节点设置在不同的列data.nodes[i].info.row,就可以创建垂直图形</p>',
'en-US': '<p>Nodes are set in different columns data.nodes[i].info.row, and vertical graphics can be created.</p>'
},
codeFiles: ['basic-usage.vue']
},
@ -18,11 +17,11 @@ export default {
demoId: 'horizon',
name: {
'zh-CN': '水平图形',
'en-US': 'events'
'en-US': 'Horizontal Graph'
},
desc: {
'zh-CN': '<p><p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>节点设置在不同的列data.nodes[i].info.col,就可以创建水平图形</p>',
'en-US': '<p>Nodes are set in different columns data.nodes[i].info.col, and horizontal graphics can be created.</p>'
},
codeFiles: ['horizon.vue']
},
@ -30,11 +29,11 @@ export default {
demoId: 'dot-vertical',
name: {
'zh-CN': '点模式-垂直图形',
'en-US': 'events'
'en-US': 'Point Mode - Vertical Graph'
},
desc: {
'zh-CN': '<p><p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p></p>',
'en-US': '<p></p>'
},
codeFiles: ['dot-vertical.vue']
},
@ -42,11 +41,11 @@ export default {
demoId: 'dot-horizon',
name: {
'zh-CN': '点模式-水平图形',
'en-US': 'events'
'en-US': 'Point Mode - Horizontal Graph'
},
desc: {
'zh-CN': '<p><p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p></p>',
'en-US': '<p></p>'
},
codeFiles: ['dot-horizon.vue']
},
@ -54,11 +53,11 @@ export default {
demoId: 'dot-horizon-async',
name: {
'zh-CN': '点模式-水平图形-异步',
'en-US': 'events'
'en-US': 'Point Mode - Horizontal Graph - Asynchronous'
},
desc: {
'zh-CN': '<p><p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p></p>',
'en-US': '<p></p>'
},
codeFiles: ['dot-horizon-async.vue']
},
@ -70,7 +69,7 @@ export default {
},
desc: {
'zh-CN': '<p><p>',
'en-US': '<p>bbutton click</p>'
'en-US': '<p>Point Mode - Vertical Graph - Asynchronous</p>'
},
codeFiles: ['dot-vertical-async.vue']
},
@ -78,11 +77,11 @@ export default {
demoId: 'holistic',
name: {
'zh-CN': '全景图',
'en-US': 'events'
'en-US': 'Panoramic view'
},
desc: {
'zh-CN': '<p><p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p></p>',
'en-US': '<p></p>'
},
codeFiles: ['holistic.vue']
},
@ -90,14 +89,14 @@ export default {
demoId: 'holistic-fork',
name: {
'zh-CN': '全景图-分叉',
'en-US': 'events'
'en-US': 'Panorama - Fork'
},
desc: {
'zh-CN': '<p><p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p></p>',
'en-US': '<p></p>'
},
codeFiles: ['holistic-fork.vue']
}
],
apis: []
}
}

View File

@ -10,7 +10,7 @@ export default {
},
desc: {
'zh-CN': '<p>通过 `image-size` 设置预览的图片尺寸大小,通过`round`设置是否展示圆形。</p>',
'en-US': '<p>button type</p>'
'en-US': '<p>Use `image-size` to set the size of the previewed image and use `round` to set whether to display a circle.</p>'
},
codeFiles: ['basic-usage.vue']
},
@ -19,11 +19,11 @@ export default {
demoId: 'show-hover',
name: {
'zh-CN': '图片悬浮',
'en-US': 'events'
'en-US': 'Image floating'
},
desc: {
'zh-CN': '<p>通过 `show-hover` 设置预览的图片的悬浮效果。<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>通过 `show-hover` 设置预览的图片的悬浮效果。</p>',
'en-US': '<p>Use `show-hover` to set the floating effect of the previewed image.</p>'
},
codeFiles: ['show-hover.vue']
},
@ -31,12 +31,12 @@ export default {
demoId: 'auto-fit-container-size',
name: {
'zh-CN': '自适应容器尺寸',
'en-US': 'events'
'en-US': 'Adaptive Container Size'
},
desc: {
'zh-CN':
'<p>可通过 `fit` 属性确定图片如何适应到容器框,同原生 css 的 object-fit 属性。<br> object-fit 说明<br>fill被替换的内容将被缩放以在填充元素的内容框时保持其宽高比<br>contain被替换的内容大小可以填充元素的内容框<br> cover被替换的内容大小保持其宽高比同时填充元素的整个内容框<br>none被替换的内容尺寸不会被改变<br>scale-down内容的尺寸就像是指定了 none 或 contain取决于哪一个将导致更小的对象尺寸。<p>',
'en-US': '<p>bbutton click</p>'
'<p>可通过 `fit` 属性确定图片如何适应到容器框,同原生 css 的 object-fit 属性。<br> object-fit 说明<br>fill被替换的内容将被缩放以在填充元素的内容框时保持其宽高比<br>contain被替换的内容大小可以填充元素的内容框<br> cover被替换的内容大小保持其宽高比同时填充元素的整个内容框<br>none被替换的内容尺寸不会被改变<br>scale-down内容的尺寸就像是指定了 none 或 contain取决于哪一个将导致更小的对象尺寸。</p>',
'en-US': '<p>You can use the `fit` attribute to determine how an image adapts to the container box, which is the same as the object-fit attribute of the native CSS.<br>Object-fit Description<br>fill: The replaced content is scaled to maintain its aspect ratio when filling the element\'s content box.<br>cover: The size of the replaced content keeps its aspect ratio and fills the entire content box of the element.<br>none: The size of the content to be replaced is not changed.<br>scale-down: The size of the content is as if none or contain were specified, depending on which would result in a smaller object size.</p>'
},
codeFiles: ['auto-fit-container-size.vue']
},
@ -44,11 +44,11 @@ export default {
demoId: 'preview-src-list',
name: {
'zh-CN': '预览大图',
'en-US': 'events'
'en-US': 'Preview Large Image'
},
desc: {
'zh-CN': '<p>通过 `preview-src-list` 开启预览大图的功能,通过添加`show-index`开启图片序列号展示。<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>通过 `preview-src-list` 开启预览大图的功能,通过添加`show-index`开启图片序列号展示。</p>',
'en-US': '<p>Use the `preview-src-list` command to enable the function of previewing large images, and add the `show-index` command to enable the display of image sequence numbers.</p>'
},
codeFiles: ['preview-src-list.vue']
},
@ -56,11 +56,11 @@ export default {
demoId: 'round',
name: {
'zh-CN': '尺寸类型',
'en-US': 'events'
'en-US': 'Size Type'
},
desc: {
'zh-CN': '<p>通过 `image-size` 设置预览的图片尺寸大小,通过 round 设置是否展示圆形。<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>通过 `image-size` 设置预览的图片尺寸大小,通过 round 设置是否展示圆形。</p>',
'en-US': '<p>Use `image-size` to set the size of the previewed image and use round to set whether to display a circle.</p>'
},
codeFiles: ['round.vue']
},
@ -68,11 +68,11 @@ export default {
demoId: 'custom-placeholder',
name: {
'zh-CN': '占位内容',
'en-US': 'events'
'en-US': 'Placeholder Content'
},
desc: {
'zh-CN': '<p>可通过 `slot = placeholder` 自定义占位内容。<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>可通过 `slot = placeholder` 自定义占位内容。</p>',
'en-US': '<p>You can use `slot = placeholder` to customize the placeholder.</p>'
},
codeFiles: ['custom-placeholder.vue']
},
@ -80,12 +80,12 @@ export default {
demoId: 'lazy-load',
name: {
'zh-CN': '懒加载',
'en-US': 'events'
'en-US': 'Lazy loading'
},
desc: {
'zh-CN':
'<p>可通过 `lazy` 开启懒加载功能,当图片滚动到可视范围内才会加载。可通过 `scroll-container` 来设置滚动容器,若未定义,则为最近一个 `overflow` 值为 `auto` 或 `scroll` 的父元素。<p>',
'en-US': '<p>bbutton click</p>'
'<p>可通过 `lazy` 开启懒加载功能,当图片滚动到可视范围内才会加载。可通过 `scroll-container` 来设置滚动容器,若未定义,则为最近一个 `overflow` 值为 `auto` 或 `scroll` 的父元素。</p>',
'en-US': '<p>You can use `lazy` to enable lazy loading. Images are loaded only when they are scrolled to the visible range. You can use `scroll-container` to set the scrolling container. If it is not defined, the scrolling container is the parent element whose latest `overflow` value is `auto` or `scroll`.</p>'
},
codeFiles: ['lazy-load.vue']
},
@ -93,11 +93,11 @@ export default {
demoId: 'preview-z-index',
name: {
'zh-CN': '图片预览层级',
'en-US': 'events'
'en-US': 'Image preview level'
},
desc: {
'zh-CN': '<p>可通过 `z-index` 设置预览图片的层级。<p>',
'en-US': '<p>bbutton click</p>'
'en-US': '<p>You can use `z-index` to set the preview image level.</p>'
},
codeFiles: ['preview-z-index.vue']
},
@ -105,11 +105,11 @@ export default {
demoId: 'load-event',
name: {
'zh-CN': '加载成功事件',
'en-US': 'events'
'en-US': 'Loading success event'
},
desc: {
'zh-CN': '<p>图片加载成功触发 `load` 事件。<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>图片加载成功触发 `load` 事件。</p>',
'en-US': '<p>The `load` event is triggered when the image is loaded successfully.</p>'
},
codeFiles: ['load-event.vue']
},
@ -117,11 +117,11 @@ export default {
demoId: 'load-error',
name: {
'zh-CN': '加载失败事件',
'en-US': 'events'
'en-US': 'Loading failure event'
},
desc: {
'zh-CN': '<p>图片加载失败触发 `error` 事件。<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>图片加载失败触发 `error` 事件。</p>',
'en-US': '<p>The `error` event is triggered when the image fails to be loaded.</p>'
},
codeFiles: ['load-error.vue']
},
@ -129,11 +129,11 @@ export default {
demoId: 'custom-load-failed-text',
name: {
'zh-CN': '加载失败',
'en-US': 'events'
'en-US': 'Loading failed.'
},
desc: {
'zh-CN': '<p>可通过 `slot = error` 自定义加载失败内容。<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>可通过 `slot = error` 自定义加载失败内容。</p>',
'en-US': '<p>You can run the `slot = error` command to customize the content that fails to be loaded.</p>'
},
codeFiles: ['custom-load-failed-text.vue']
},
@ -141,11 +141,11 @@ export default {
demoId: 'preview-in-dialog',
name: {
'zh-CN': '对话框中预览图片',
'en-US': 'events'
'en-US': 'Preview picture in dialog box'
},
desc: {
'zh-CN': '<p>在 `dialog-box` 元素中嵌入 image 进行图片预览。<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>在 `dialog-box` 元素中嵌入 image 进行图片预览。</p>',
'en-US': '<p>Embed the image in the `dialog-box` element for image preview.</p>'
},
codeFiles: ['preview-in-dialog.vue']
},
@ -153,11 +153,11 @@ export default {
demoId: 'thumbnail',
name: {
'zh-CN': '缩略图视图(非模态)',
'en-US': 'events'
'en-US': 'Thumbnail view (non-modal)'
},
desc: {
'zh-CN': '<p>通过 `is-thumbnail` 属性开启非模态缩略图视图的功能<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>通过 `is-thumbnail` 属性开启非模态缩略图视图的功能</p>',
'en-US': '<p>Enable the modeless thumbnail view through the `is-thumbnail` property<</p>'
},
codeFiles: ['thumbnail.vue']
},
@ -165,12 +165,12 @@ export default {
demoId: 'thumbnail-modal-view',
name: {
'zh-CN': '缩略图视图(模态)',
'en-US': 'events'
'en-US': 'Thumbnail view (modal)'
},
desc: {
'zh-CN':
'<p>通过 `modal-view` 属性开启模态缩略图视图的功能可以通过modal-height属性设置模态框内对应的高度默认值为 400。<p>',
'en-US': '<p>bbutton click</p>'
'<p>通过 `modal-view` 属性开启模态缩略图视图的功能可以通过modal-height属性设置模态框内对应的高度默认值为 400。</p>',
'en-US': '<p>You can use the `modal-view` attribute to enable the modal thumbnail view function. You can use the modal-height attribute to set the height of the modal box. The default value is 400.</p>'
},
codeFiles: ['thumbnail-modal-view.vue']
},
@ -178,11 +178,11 @@ export default {
demoId: 'menu-view',
name: {
'zh-CN': '目录视图(非模态)',
'en-US': 'events'
'en-US': 'Catalog View (Nonmodal)'
},
desc: {
'zh-CN': '<p>通过 `is-menu-view` 属性开启非模态目录视图的功能<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>通过 `is-menu-view` 属性开启非模态目录视图的功能</p>',
'en-US': '<p>Use the `is-menu-view` attribute to enable the non-modal catalog view.</p>'
},
codeFiles: ['menu-view.vue']
},
@ -190,12 +190,12 @@ export default {
demoId: 'menu-modal-view',
name: {
'zh-CN': '目录视图(模态)',
'en-US': 'events'
'en-US': 'Catalog View (modal)'
},
desc: {
'zh-CN':
'<p>通过 `modal-view` 属性开启模态目录视图的功能,可以通过`modal-height`属性设置模态框内对应的高度,默认值为 400。<p>',
'en-US': '<p>bbutton click</p>'
'<p>通过 `modal-view` 属性开启模态目录视图的功能,可以通过`modal-height`属性设置模态框内对应的高度,默认值为 400。</p>',
'en-US': '<p>Use the `modal-view` attribute to enable the modal directory view function. You can use the `modal-height` attribute to set the height of the modal box. The default value is 400.</p>'
},
codeFiles: ['menu-modal-view.vue']
},
@ -203,11 +203,11 @@ export default {
demoId: 'thumbnail-viewer-bg',
name: {
'zh-CN': '缩略图视图',
'en-US': 'events'
'en-US': 'Thumbnail View'
},
desc: {
'zh-CN': '<p>缩略图视图背景<p>',
'en-US': '<p>bbutton click</p>'
'en-US': '<p>Thumbnail View Background</p>'
},
codeFiles: ['thumbnail-viewer-bg.vue']
},
@ -215,11 +215,11 @@ export default {
demoId: 'menu-viewer-bg',
name: {
'zh-CN': '目录视图背景',
'en-US': 'events'
'en-US': 'Catalog View Background'
},
desc: {
'zh-CN': '<p>目录视图<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>目录视图</p>',
'en-US': '<p>Table of Contents View</p>'
},
codeFiles: ['menu-viewer-bg.vue']
},
@ -227,11 +227,11 @@ export default {
demoId: 'thumbnail-rename',
name: {
'zh-CN': '视图文件名-缩略图',
'en-US': 'events'
'en-US': 'View File Name - Thumbnail'
},
desc: {
'zh-CN': '<p>视图文件名-缩略图<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>视图文件名-缩略图</p>',
'en-US': '<p>View File Name - Thumbnail</p>'
},
codeFiles: ['thumbnail-rename.vue']
},
@ -239,14 +239,83 @@ export default {
demoId: 'menu-rename',
name: {
'zh-CN': '视图文件名-目录',
'en-US': 'events'
'en-US': 'View File Name - Directory'
},
desc: {
'zh-CN': '<p>视图文件名-目录<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>视图文件名-目录</p>',
'en-US': '<p>View File Name - Directory</p>'
},
codeFiles: ['menu-rename.vue']
}
],
apis: []
apis: [
{
'name': 'Image',
'type': 'component',
'props': [
{
'name': 'image-size ',
'type': 'String',
'defaultValue': '',
'desc': {
'zh-CN': '设置预览的图片的大小',
'en-US': 'Sets the size of the previewed picture.'
},
'demoId': 'round'
},
{
'name': 'preview-visible',
'type': 'String',
'defaultValue': '',
'desc': {
'zh-CN': '开启移动端预览大图的功能',
'en-US': 'Enable the function of previewing large images on mobile devices.'
},
'demoId': ''
},
{
'name': 'round',
'type': 'String',
'defaultValue': '',
'desc': {
'zh-CN': '通过 round 设置是否展示圆形',
'en-US': 'Use round to set whether to display a circle.'
},
'demoId': 'round'
},
{
'name': 'show-hover',
'type': 'String',
'defaultValue': '',
'desc': {
'zh-CN': '设置预览的图片的悬浮效果',
'en-US': 'Sets the floating effect of the previewed image.'
},
'demoId': 'show-hover'
},
{
'name': 'show-index',
'type': 'String',
'defaultValue': '',
'desc': {
'zh-CN': '开启图片序列号展示',
'en-US': 'Enable the display of image serial numbers.'
},
'demoId': 'preview-src-list'
},
],
'events': [
{
'name': 'delete',
'type': 'Function()',
'defaultValue': '',
'desc': {
'zh-CN': '图片删除触发',
'en-US': 'Triggered by image deletion.'
},
'demoId': ''
}
],
},
]
}

View File

@ -1,8 +1,7 @@
export default {
column: '2',
owner: '',
demos: [
{
demos: [{
demoId: 'basic-usage',
name: {
'zh-CN': '基本用法',
@ -30,7 +29,7 @@ export default {
demoId: 'loosing-text',
name: {
'zh-CN': '下拉可刷新的文字提示',
'en-US': 'basic usage'
'en-US': 'Drop-down refreshable text prompt'
},
desc: {
'zh-CN': '<p>通过属性 <code>loosing-text</code> 设置 pulling 提示文字</p>',
@ -42,7 +41,7 @@ export default {
demoId: 'success-text',
name: {
'zh-CN': '刷新成功的文字',
'en-US': 'basic usage'
'en-US': 'Texts that are successfully refreshed'
},
desc: {
'zh-CN': '<p>通过属性 <code>success-text</code> 设置 pulling 提示文字</p>',
@ -54,7 +53,7 @@ export default {
demoId: 'success-duration',
name: {
'zh-CN': '刷新成功的文字展示时长',
'en-US': '刷新成功的文字展示时长'
'en-US': 'Text display duration that is successfully refreshed.'
},
desc: {
'zh-CN': '<p>设置属性 <code>success-duration</code> 指定延时时间</p>',
@ -82,8 +81,7 @@ export default {
},
desc: {
'zh-CN': `<p>设置属性 <code>head-height</code> 为数字或字符串,例如:<code>100/'100'/'100px'/'6rem'</code></p>`,
'en-US': `<p>
Set the property <code>head-height</code> to a number or string, for example: <code>100/'100'/'100px'/'6rem'</code></p>`
'en-US': `<p>Set the property <code>head-height</code> to a number or string, for example: <code>100/'100'/'100px'/'6rem'</code></p>`
},
codeFiles: ['head-height.vue']
},
@ -112,5 +110,221 @@ export default {
codeFiles: ['pull-refresh-slot.vue']
}
],
apis: []
}
apis: [{
'name': 'pull-refresh',
'type': 'component',
'props': [{
'name': ' animationDuration',
'type': '[Number, String]',
'defaultValue': '默认值是300',
'desc': {
'zh-CN': '刷新成功后头部延时消失时间',
'en-US': 'Header delay disappearing time after successful refresh'
},
'demoId': 'animation-duration'
},
{
'name': 'disabled',
'type': 'Boolean',
'defaultValue': '默认值是false',
'desc': {
'zh-CN': '是否禁用下拉刷新',
'en-US': 'Whether to disable pull-down refresh'
},
'demoId': 'disabled'
},
{
'name': 'headHeight',
'type': '[Number, String]',
'defaultValue': '默认值是50',
'desc': {
'zh-CN': '组件头部提示区域的高度',
'en-US': 'Height of the component head prompt area'
},
'demoId': 'head-height'
},
{
'name': 'loadingOptions',
'type': 'Object',
'defaultValue': '默认值是空对象{}',
'desc': {
'zh-CN': '不使用loading插槽时内置加载组件Loading的参数Loading.service(options)',
'en-US': 'When the loading slot is not used, the loading parameter of the built-in loading component is Loading.service(options).'
},
'demoId': ''
},
{
'name': 'loadingText',
'type': 'String',
'defaultValue': '',
'desc': {
'zh-CN': '数据刷新过程的提示文本',
'en-US': 'Prompt text for the data refresh process'
},
'demoId': ''
},
{
'name': 'loosingText',
'type': 'String',
'defaultValue': '',
'desc': {
'zh-CN': '向下拖动超过阈值后可松开进行刷新的提示文本',
'en-US': 'Drag down to release the prompt text for refresh after the threshold is exceeded.'
},
'demoId': 'loosing-text'
},
{
'name': 'modelValue',
'type': 'Boolean',
'defaultValue': '默认值是false',
'desc': {
'zh-CN': '是否正在进行下拉刷新',
'en-US': 'Is the pull-down refresh in progress'
},
'demoId': ''
},
{
'name': 'pullDistance',
'type': '[Number, String]',
'defaultValue': '默认值是属性 `headHeight` 的值',
'desc': {
'zh-CN': '拖拽产生刷新的距离',
'en-US': 'Refreshing distance generated by dragging'
},
'demoId': ''
},
{
'name': 'pullingText',
'type': 'String',
'defaultValue': '',
'desc': {
'zh-CN': '向下拖动过程的提示文本',
'en-US': 'Drag down the prompt text for the procedure'
},
'demoId': 'pulling-text'
},
{
'name': 'selfSimulate',
'type': 'Boolean',
'defaultValue': '默认值是false',
'desc': {
'zh-CN': '是否开启自模拟Touch事件。如果开启那么组件只处理自身产生的模拟Touch事件忽略冒泡上来的非自身模拟事件。正常非模拟Touch事件始终不会跳过处理',
'en-US': 'Indicates whether to enable the self-simulation Touch event. If this function is enabled, the component only processes simulated Touch events generated by itself and ignores non-simulated events generated by itself. Normal non-simulated Touch events never skip processing'
},
'demoId': ''
},
{
'name': 'successDuration',
'type': '[Number, String]',
'defaultValue': '默认值是500',
'desc': {
'zh-CN': '刷新成功提示文本延时消失时间',
'en-US': 'Time for the text to disappear after the refresh is successful.'
},
'demoId': 'success-duration'
},
{
'name': 'successText',
'type': 'String',
'defaultValue': '',
'desc': {
'zh-CN': '刷新成功的提示文本',
'en-US': 'Text of the message indicating that the refresh is successful'
},
'demoId': 'success-text'
}
],
'events': [{
'name': 'change',
'type': 'Function({ status, distance })',
'defaultValue': 'status:{String 组件当前状态}distance:{Number 当前的拖动距离}',
'desc': {
'zh-CN': '在组件状态改变时抛出',
'en-US': 'Thrown when the component state changes'
},
'demoId': ''
},
{
'name': 'refresh',
'type': 'Function()',
'defaultValue': '',
'desc': {
'zh-CN': '在组件状态进入 loading 刷新数据时抛出',
'en-US': 'Thrown when the component enters the loading state to refresh data'
},
'demoId': ''
},
{
'name': 'update:modelValue',
'type': 'Function(isLoading)',
'defaultValue': 'isLoading:{Boolean 组件是否处于 loading}',
'desc': {
'zh-CN': '在组件状态进入 loading 刷新数据时抛出',
'en-US': 'Thrown when the component enters the loading state to refresh data'
},
'demoId': ''
}
],
'slots': [{
'name': 'default',
'type': '',
'defaultValue': '',
'desc': {
'zh-CN': '组件默认插槽',
'en-US': 'Component Default Slot'
},
'demoId': 'pull-refresh-slot'
},
{
'name': 'loading',
'type': '',
'defaultValue': '',
'desc': {
'zh-CN': '组件 loading 插槽,自定义 loading 状态的提示',
'en-US': 'Component loading slot, which is used to customize the loading status prompt.'
},
'demoId': 'pull-refresh-slot'
},
{
'name': 'loosing',
'type': '',
'defaultValue': '',
'desc': {
'zh-CN': '组件 loosing 插槽,自定义 loosing 状态的提示',
'en-US': 'Component loosing slot, which is used to customize the loosing status prompt.'
},
'demoId': 'pull-refresh-slot'
},
{
'name': 'normal',
'type': '',
'defaultValue': '',
'desc': {
'zh-CN': '组件 normal 插槽,自定义 normal 状态的提示',
'en-US': 'Indicates the normal slot of the component. The prompt for the normal status is customized.'
},
'demoId': 'pull-refresh-slot'
},
{
'name': 'pulling',
'type': '',
'defaultValue': '',
'desc': {
'zh-CN': '组件 pulling 插槽,自定义 pulling 状态的提示',
'en-US': 'Pull slot of the component, which is used to customize the prompt of the pull status.'
},
'demoId': 'pull-refresh-slot'
},
{
'name': 'success',
'type': '',
'defaultValue': '',
'desc': {
'zh-CN': '组件 success 插槽,自定义 success 状态的提示',
'en-US': 'Indicates the success slot of the component. The success status is customized.'
},
'demoId': 'pull-refresh-slot'
}
]
}]
}

View File

@ -1,15 +1,14 @@
export default {
column: '2',
owner: '',
demos: [
{
demos: [{
demoId: 'basic-usage',
name: {
'zh-CN': '基本用法',
'en-US': 'basic usage'
},
desc: {
'zh-CN': '<p></p>',
'zh-CN': '<p>按钮类型</p>',
'en-US': '<p>button type</p>'
},
codeFiles: ['basic-usage.vue']
@ -19,11 +18,11 @@ export default {
demoId: 'dynamic-disable',
name: {
'zh-CN': '禁用',
'en-US': 'events'
'en-US': 'disabling'
},
desc: {
'zh-CN': '<p>通过 `disabled` 设置禁用<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>通过 `disabled` 设置禁用</p>',
'en-US': '<p>Disable by setting `disabled`</p>'
},
codeFiles: ['dynamic-disable.vue']
},
@ -31,12 +30,11 @@ export default {
demoId: 'manual-control-tip',
name: {
'zh-CN': '手动控制',
'en-US': 'events'
'en-US': 'Manual control'
},
desc: {
'zh-CN':
'<p>手动控制模式,通过设置 `manual` 属性为 true 后mouseenter 和 mouseleave 事件将不会生效,然后可以通过设置 `v-model` 动态控制显示和隐藏<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>手动控制模式,通过设置 `manual` 属性为 true 后mouseenter 和 mouseleave 事件将不会生效,然后可以通过设置 `v-model` 动态控制显示和隐藏</p>',
'en-US': '<p>Manual control mode. After the `manual` attribute is set to true, the mouseenter and mouseleave events do not take effect. You can set the `v-model` to dynamically control the display and hiding of the events.</p>'
},
codeFiles: ['manual-control-tip.vue']
},
@ -44,11 +42,11 @@ export default {
demoId: 'tooltip-theme',
name: {
'zh-CN': '主题',
'en-US': 'events'
'en-US': 'Subject'
},
desc: {
'zh-CN': '<p>通过 `effect` 属性设置主题,可选值 dark/light 两种主题。<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>通过 `effect` 属性设置主题,可选值 dark/light 两种主题。</p>',
'en-US': '<p>Set the theme through the `effect` property. The options are dark and light.</p>'
},
codeFiles: ['tooltip-theme.vue']
},
@ -56,12 +54,11 @@ export default {
demoId: 'open-delay',
name: {
'zh-CN': '自动隐藏和延迟时间',
'en-US': 'events'
'en-US': 'Auto-hide and delay time'
},
desc: {
'zh-CN':
'<p>通过 `hide-after` 属性设置 Tooltip 组件出现后自动隐藏延时,单位毫秒,为 0 则不会自动隐藏。通过 `open-delay` 属性设置 Tooltip 组件延迟出现的时间,单位毫秒。<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>通过 `hide-after` 属性设置 Tooltip 组件出现后自动隐藏延时,单位毫秒,为 0 则不会自动隐藏。通过 `open-delay` 属性设置 Tooltip 组件延迟出现的时间,单位毫秒。<p>',
'en-US': '<p>The `hide-after` attribute is used to set the automatic hiding delay of the Tooltip component, in milliseconds. If the value is 0, the Tooltip component is not automatically hidden. The `open-delay` property is used to set the delay for the Tooltip component to appear, in milliseconds.</p>'
},
codeFiles: ['open-delay.vue']
},
@ -69,11 +66,11 @@ export default {
demoId: 'tooltip-offset',
name: {
'zh-CN': '偏移量',
'en-US': 'events'
'en-US': 'Offset'
},
desc: {
'zh-CN': '<p>通过 `offset` 属性设置 Tooltip 组件出现位置的偏移量。<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>通过 `offset` 属性设置 Tooltip 组件出现位置的偏移量。</p>',
'en-US': '<p>Use the `offset` property to set the offset where the Tooltip component appears.</p>'
},
codeFiles: ['tooltip-offset.vue']
},
@ -81,11 +78,11 @@ export default {
demoId: 'enterable',
name: {
'zh-CN': '鼠标是否可进入',
'en-US': 'events'
'en-US': 'Whether the mouse can be accessed'
},
desc: {
'zh-CN': '<p>通过 `enterable` 属性设置鼠标是否可进入到 tooltip 中。<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>通过 `enterable` 属性设置鼠标是否可进入到 tooltip 中。</p>',
'en-US': '<p>Use the `enterable` attribute to set whether the mouse can access the tooltip.</p>'
},
codeFiles: ['enterable.vue']
},
@ -93,11 +90,11 @@ export default {
demoId: 'visible-arrow',
name: {
'zh-CN': '是否显示箭头',
'en-US': 'events'
'en-US': 'Whether to display arrows'
},
desc: {
'zh-CN': '<p>通过 `visible-arrow` 属性设置是否显示 Tooltip 箭头。<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>通过 `visible-arrow` 属性设置是否显示 Tooltip 箭头。</p>',
'en-US': '<p>Use the `visible-arrow` property to set whether to display the Tooltip arrow.</p>'
},
codeFiles: ['visible-arrow.vue']
},
@ -105,11 +102,11 @@ export default {
demoId: 'popper-class',
name: {
'zh-CN': '添加样式类名',
'en-US': 'events'
'en-US': 'Add Style Class Name'
},
desc: {
'zh-CN': '<p>通过 `popper-class` 属性为 Tooltip 的 popper 添加类名。<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>通过 `popper-class` 属性为 Tooltip 的 popper 添加类名。</p>',
'en-US': '<p>Use the `popper-class` attribute to add a class name to the tooltip\'s popper.</p>'
},
codeFiles: ['popper-class.vue']
},
@ -117,11 +114,11 @@ export default {
demoId: 'tooltip-content',
name: {
'zh-CN': '插槽',
'en-US': 'events'
'en-US': 'Slots'
},
desc: {
'zh-CN': '<p>设置过通过 `content` 插槽添加自定义内容。滤类型<p>',
'en-US': '<p>bbutton click</p>'
'en-US': '<p>Set to add custom content through the `content` slot. Filter Type</p>'
},
codeFiles: ['tooltip-content.vue']
},
@ -129,12 +126,11 @@ export default {
demoId: 'popper-options',
name: {
'zh-CN': 'popper 配置',
'en-US': 'events'
'en-US': 'Popper Configuration'
},
desc: {
'zh-CN':
'<p>通过 `popper-options` 属性为 Tooltip 的 popper 配置参数,具体可参考[popper.js](https://popper.js.org/)<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>通过 `popper-options` 属性为 Tooltip 的 popper 配置参数,具体可参考[popper.js](https://popper.js.org/)</p>',
'en-US': '<p>Use the `popper-options` attribute to configure popper parameters for Tooltip. For details, see [popper.js](https://popper.js.org/).</p>'
},
codeFiles: ['popper-options.vue']
},
@ -142,11 +138,11 @@ export default {
demoId: 'popper-options-bubbling',
name: {
'zh-CN': 'popper 配置通过 bubbling 控制 tip 位置',
'en-US': 'events'
'en-US': 'The popper configuration uses bubbling to control the tip position.'
},
desc: {
'zh-CN': '<p>popperOptions.bubbling 配置为 true 时,所有的父元素包含滚动条,滚动时都会动态改变 tip 的位置<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>popperOptions.bubbling 配置为 true 时,所有的父元素包含滚动条,滚动时都会动态改变 tip 的位置</p>',
'en-US': '<p>When popperOptions.bubbling is set to true, all parent elements contain scroll bars. During scrolling, the position of tip is dynamically changed.</p>'
},
codeFiles: ['popper-options-bubbling.vue']
},
@ -154,11 +150,11 @@ export default {
demoId: 'tabindex',
name: {
'zh-CN': 'tabindex 配置',
'en-US': 'events'
'en-US': 'tabindex configuration'
},
desc: {
'zh-CN': '<p>通过配置 `tabindex` 配置的属性会自动添加到该组件的触发原上。<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>通过配置 `tabindex` 配置的属性会自动添加到该组件的触发原上。</p>',
'en-US': '<p>By configuring `tabindex`, the configured attributes are automatically added to the trigger source of the component.</p>'
},
codeFiles: ['tabindex.vue']
},
@ -166,12 +162,11 @@ export default {
demoId: 'content-pre',
name: {
'zh-CN': '文本预格式化',
'en-US': 'events'
'en-US': 'Text Preformatting'
},
desc: {
'zh-CN':
'<p>配置 `pre` 为 `true`,就会预格式化 `content` 文本。<br>被包围在 `<pre></pre>` 标签元素中的文本会保留空格和换行符,文本也会呈现为等宽字体。<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>配置 `pre` 为 `true`,就会预格式化 `content` 文本。<br>被包围在 `<pre></pre>` 标签元素中的文本会保留空格和换行符,文本也会呈现为等宽字体。</p>',
'en-US': '<p>If `pre` is set to `true`, the `content` text is preformatted. <br>Text enclosed in the `<pre></pre>` tag element retains spaces and newline characters, and the text is rendered in an equal-width font.</p>'
},
codeFiles: ['content-pre.vue']
},
@ -179,11 +174,11 @@ export default {
demoId: 'content-render',
name: {
'zh-CN': '自定义渲染',
'en-US': 'events'
'en-US': 'Custom Rendering'
},
desc: {
'zh-CN': '<p>使用属性 `renderContent` 配置自定义渲染方法<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>使用属性 `renderContent` 配置自定义渲染方法</p>',
'en-US': '<p>Configure a custom rendering method using the property `renderContent`</p>'
},
codeFiles: ['content-render.vue']
},
@ -191,15 +186,14 @@ export default {
demoId: 'z-index',
name: {
'zh-CN': '弹出层 zIndex',
'en-US': 'events'
'en-US': 'z-index'
},
desc: {
'zh-CN':
'<p>设置`z-index`属性为`relative`时,弹出层样式属性 zIndex 值参考 Reference 及其父级 Dom。<br>设置`z-index`属性为默认值`next`时,弹出层样式属性 zIndex 值由组件库内部维护。<p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>设置`z-index`属性为`relative`时,弹出层样式属性 zIndex 值参考 Reference 及其父级 Dom。<br>设置`z-index`属性为默认值`next`时,弹出层样式属性 zIndex 值由组件库内部维护。</p>',
'en-US': '<p>When the `z-index` attribute is set to `relative`, the value of zIndex of the pop-up layer style attribute is Reference and its parent Dom. <br>When the `z-index` attribute is set to the default value `next`, the value of the pop-up layer style attribute zIndex is maintained by the component library.</p>'
},
codeFiles: ['z-index.vue']
}
],
apis: []
}
}

View File

@ -0,0 +1,26 @@
<template>
<div class="demo-alert-base">
<tiny-alert description="type 为默认值 info"></tiny-alert>
<tiny-alert type="error" description="type 为 error"></tiny-alert>
<tiny-alert type="success" description="type 为 success"></tiny-alert>
<tiny-alert type="warning">
<span>type warning且使用内容插槽</span>
</tiny-alert>
</div>
</template>
<script>
import { Alert } from '@opentiny/vue'
export default {
components: {
TinyAlert: Alert
}
}
</script>
<style scoped>
.demo-alert-base .tiny-mobile-alert {
margin-bottom: 8px;
}
</style>

View File

@ -0,0 +1,13 @@
<template>
<tiny-alert center description="文字居中"></tiny-alert>
</template>
<script>
import { Alert } from '@opentiny/vue'
export default {
components: {
TinyAlert: Alert
}
}
</script>

View File

@ -1,18 +1,36 @@
<template>
<div class="alert-wrap">
<tiny-alert>默认关闭按钮</tiny-alert>
<tiny-alert :closable="false"> 不可关闭 </tiny-alert>
<tiny-alert close-text="关闭"> 自定义关闭按钮为文本 </tiny-alert>
<tiny-alert type="warning" description="type 为 warning"></tiny-alert>
<p>1. <code>closable</code> 属性设成 false , 提示不可关闭</p>
<tiny-alert :closable="false"> 这个提示不可关闭 </tiny-alert>
<br />
<p>2. <code>auto-hide</code> 属性设成 true , 提示将在2秒后自动关闭</p>
自动关闭: <tiny-switch v-model="autoHide"></tiny-switch>
<tiny-alert :auto-hide="autoHide"> {{ autoHide ? '2秒后将自动关闭' : '点击开关查看自动关闭功能' }} </tiny-alert>
<br />
<p>3. 通过 <code>close-text</code> 属性自定义关闭按钮文本</p>
<tiny-alert :close-text="closeText"> close-text属性使用示例 </tiny-alert>
<br />
<p>4. 提示关闭时触发 <code>close</code> 事件</p>
<tiny-alert @close="close"> close-text属性使用示例 </tiny-alert>
</div>
</template>
<script lang="jsx">
import { Alert } from '@opentiny/vue'
<script>
import { Alert, Switch } from '@opentiny/vue'
export default {
components: {
TinyAlert: Alert
TinyAlert: Alert,
TinySwitch: Switch
},
data() {
return {
autoHide: false,
closeText: '自定义关闭',
}
},
methods: {
close() {

View File

@ -0,0 +1,30 @@
<template>
<div class="alert-target-demo">
<div class="alert-wrap" ref="target">
<tiny-tabs activeName="first" activeColor="blue">
<tiny-tab-item title="标签1" name="first"> 内容1 </tiny-tab-item>
<tiny-tab-item title="标签2" name="second"> 内容2 </tiny-tab-item>
<tiny-tab-item title="标签3" name="third"> 内容3 </tiny-tab-item>
</tiny-tabs>
</div>
<tiny-alert target="target">展示在标签栏上</tiny-alert>
</div>
</template>
<script>
import { Alert, Tabs, TabItem } from '@opentiny/vue'
export default {
components: {
TinyAlert: Alert,
TinyTabs: Tabs,
TinyTabItem: TabItem
}
}
</script>
<style>
.alert-wrap .tiny-mobile-alert {
margin-bottom: 8px;
}
</style>

View File

@ -2,6 +2,17 @@ export default {
column: '2',
owner: '',
demos: [
{
'demoId': 'base',
'name': { 'zh-CN': '基本用法', 'en-US': 'Basic Usage' },
'desc': {
'zh-CN':
'通过 <code>type</code> 设置不同的类型 可选值success | warning | info | error 默认值success。<br> 同时可通过 <code>default</code> 默认插槽自定义提示内容。',
'en-US':
'Set different types through <code>type</code>. The options are success | warning | info | error. The default value is success. <br/> You can customize the prompt content through the <code>default</code> slot. '
},
'codeFiles': ['basic-usage.vue']
},
{
demoId: 'custom-close',
name: {
@ -26,6 +37,15 @@ export default {
},
codeFiles: ['icon.vue']
},
{
'demoId': 'center',
'name': { 'zh-CN': '文字居中', 'en-US': 'Center text' },
'desc': {
'zh-CN': '<p>通过 <code>center</code> 属性可使文字显示居中。</p>\n',
'en-US': '<p>You can use the <code>center</code> property to center the text. </p>\n'
},
'codeFiles': ['center.vue']
},
{
demoId: 'size',
name: {
@ -38,6 +58,18 @@ export default {
},
codeFiles: ['size.vue']
},
{
demoId: 'target',
name: {
'zh-CN': '指定挂载节点',
'en-US': 'Specify display node'
},
desc: {
'zh-CN': '通过<code> target </code>属性绑定要挂载的容器ref值实现自定义展示位置',
'en-US': 'Specify display position'
},
codeFiles: ['target.vue']
},
{
demoId: 'slot-default',
name: {
@ -56,6 +88,13 @@ export default {
name: 'alert', // 组件名称展示使用
type: 'component', // API 类型
properties: [
{
'name': 'center',
'type': 'boolean',
'defaultValue': 'false',
'desc': { 'zh-CN': '文字是否居中', 'en-US': 'Whether the text is centered' },
'demoId': 'center'
},
{
name: 'closable',
type: 'Boolean',
@ -106,6 +145,17 @@ export default {
},
demoId: 'size'
},
{
name: 'target',
type: 'String',
defaultValue: '',
desc: {
'zh-CN': '挂载容器的ref值通过该属性可以让组件展示在对应容器的顶部',
'en-US':
'Mounted container reference, this property allows the component to be displayed at the top of the corresponding container.'
},
demoId: 'target'
},
{
name: 'type',
type: 'String',

View File

@ -0,0 +1,33 @@
<template>
<div class="checkbox-wrap">
<p>当前选中的值为{{ checked1 }}</p>
<tiny-checkbox v-model="checked1" label="复选框1"></tiny-checkbox>
<p>使用插槽</p>
<tiny-checkbox v-model="checked2">
<span style="color: red">当前选中的值为{{ checked2 }}</span>
</tiny-checkbox>
</div>
</template>
<script>
import { Checkbox } from '@opentiny/vue'
export default {
components: {
TinyCheckbox: Checkbox
},
data() {
return {
checked1: true,
checked2: false
}
}
}
</script>
<style scoped>
.checkbox-wrap {
padding: 20px;
}
</style>

View File

@ -1,19 +1,14 @@
<template>
<div class="checkbox-wrap">
<tiny-checkbox-group v-model="checked">
<tiny-checkbox label="复选框1">
<span style="color: blue">复选框1</span>
</tiny-checkbox>
<tiny-checkbox label="复选框2">
<span style="color: red">复选框2</span>
</tiny-checkbox>
<tiny-checkbox label="复选框1"></tiny-checkbox>
<tiny-checkbox label="复选框2"></tiny-checkbox>
</tiny-checkbox-group>
<br />
当前选中的值为{{ checked }}
<p>当前选中的值为{{ checked }}</p>
</div>
</template>
<script lang="jsx">
<script>
import { Checkbox, CheckboxGroup } from '@opentiny/vue'
export default {
@ -29,7 +24,7 @@ export default {
}
</script>
<style>
<style scoped>
.checkbox-wrap {
padding: 20px;
}

View File

@ -3,13 +3,14 @@
<tiny-checkbox-group v-model="checked">
<tiny-checkbox label="复选框1" name="name"></tiny-checkbox>
<tiny-checkbox label="复选框2" disabled></tiny-checkbox>
<tiny-checkbox label="复选框3" disabled></tiny-checkbox>
</tiny-checkbox-group>
<br />
当前选中的值为{{ checked }}
</div>
</template>
<script lang="jsx">
<script>
import { Checkbox, CheckboxGroup } from '@opentiny/vue'
export default {
@ -19,13 +20,13 @@ export default {
},
data() {
return {
checked: ['复选框1']
checked: ['复选框1', '复选框2']
}
}
}
</script>
<style>
<style scoped>
.checkbox-wrap {
padding: 20px;
}

View File

@ -4,7 +4,7 @@
</div>
</template>
<script lang="jsx">
<script>
import { Checkbox } from '@opentiny/vue'
export default {
@ -24,7 +24,7 @@ export default {
}
</script>
<style>
<style scoped>
.checkbox-wrap {
padding: 20px;
}

View File

@ -0,0 +1,49 @@
<template>
<div class="checkbox-wrap">
<p>
1. <code>checkbox-group</code> 设置 <code>icon-position</code>属性指定其中所有
<code>checkbox</code> 子选项的同名属性
</p>
<tiny-checkbox-group v-model="checked1" icon-position="top">
<tiny-checkbox label="复选框1">
<span style="display: block;margin-bottom: 10px;"
>第1个选项内容第1个选项内容第1个选项内容第1个选项内容第1个选项内容第1个选项内容</span
>
</tiny-checkbox>
<tiny-checkbox label="复选框2">
<span
>第2个选项内容第2个选项内容第2个选项内容第2个选项内容第2个选项内容</span
>
</tiny-checkbox>
</tiny-checkbox-group>
<br />
<p>2. 也可以给单个 <code>checkbox</code> 复选框设置 <code>icon-position</code>属性</p>
<tiny-checkbox v-model="checked2" icon-position="top">
<span>很长的label很长的label很长的label很长的label很长的label</span>
</tiny-checkbox>
</div>
</template>
<script>
import { Checkbox, CheckboxGroup } from '@opentiny/vue'
export default {
components: {
TinyCheckbox: Checkbox,
TinyCheckboxGroup: CheckboxGroup
},
data() {
return {
checked1: ['复选框1'],
checked2: false
}
}
}
</script>
<style scoped>
.checkbox-wrap {
padding: 20px;
}
</style>

View File

@ -7,7 +7,7 @@
</div>
</template>
<script lang="jsx">
<script>
import { Checkbox, CheckboxGroup } from '@opentiny/vue'
export default {
@ -48,7 +48,7 @@ export default {
}
</script>
<style>
<style scoped>
.checkbox-wrap {
padding: 20px;
}

View File

@ -6,7 +6,7 @@
</div>
</template>
<script lang="jsx">
<script>
import { Checkbox } from '@opentiny/vue'
export default {
@ -21,7 +21,7 @@ export default {
}
</script>
<style>
<style scoped>
.checkbox-wrap {
padding: 20px;
}

View File

@ -3,16 +3,81 @@ export default {
owner: '',
demos: [
{
demoId: 'default',
demoId: 'basic-usage',
name: {
'zh-CN': '插槽',
'en-US': 'button type'
'zh-CN': '基本使用',
'en-US': 'basic-usage'
},
desc: {
'zh-CN': '<p>默认插槽</p>',
'en-US': '<p>button type</p>'
'zh-CN':
'<p>通过 <code>v-model/modelValue</code> 属性绑定勾选值,<code>label</code> 或 <code>default</code> 插槽绑定标签文本。</p>',
'en-US':
'<p>Bind the checked value through the <code>v-model/modelValue/code> attribute and the <code>label/code> props or <code>default/code> slot to bind the label text.</p>'
},
codeFiles: ['default.vue']
codeFiles: ['basic-usage.vue']
},
{
demoId: 'checkbox-group',
name: {
'zh-CN': '复选框组',
'en-US': 'checkbox group'
},
desc: {
'zh-CN':
'<p>通过 <code>checkbox-group</code> 可以将多个 <code>checkbox</code> 元素管理为一组,在 <code>checkbox-group</code> 中使用 <code>v-model</code> 绑定 Array 类型的变量即可实现双向绑定。 <code>checkbox</code> 的 <code>label</code> 属性是其对应的值,若该标签中无内容,则该属性也充当 <code>checkbox</code> 的描述文本。 <code>label</code> 与数组中的元素值相对应,如果存在指定的值则为选中状态,否则为不选中。</p>',
'en-US':
'<p>Manages multiple <code>checkbox</code> elements into a group through the <code>checkbox-group</code> element. In <code>checkbox-group</code> , use <code>v-model</code> to bind variables of the Array type to implement bidirectional binding. The <code>label</code> attribute of the <code>checkbox</code> is its corresponding value. If there is no content in the tag, the attribute also serves as the introduction after the checkbox. <code>label</code> corresponds to the element value in the array. If the specified value exists, the value is selected. Otherwise, the value is not selected. </p>'
},
codeFiles: ['checkbox-group.vue']
},
{
demoId: 'indeterminate',
name: {
'zh-CN': '全选与半选',
'en-US': 'Set the all-selected and indeterminate state'
},
desc: {
'zh-CN': '<p>全选与半选</p>',
'en-US': '<p></p>'
},
codeFiles: ['indeterminate.vue']
},
{
demoId: 'disabled',
name: {
'zh-CN': '禁用',
'en-US': 'disabled'
},
desc: {
'zh-CN': '<p>通过 <code>disabled</code> 设置禁用。</p>',
'en-US': '<p>The demo of <code>disabled<code> attribute.</p>'
},
codeFiles: ['disabled.vue']
},
{
demoId: 'custom-value',
name: {
'zh-CN': '自定义取值',
'en-US': 'custom value'
},
desc: {
'zh-CN': '<p>通过 <code>true-label</code> 自定义选中值,<code>false-label</code> 自定义未选中值。</p>',
'en-US':
'<p>Customize the selected value with <code>true-label</code> and the unselected value with <code>false-label</code>.</p>'
},
codeFiles: ['true-false-label.vue']
},
{
demoId: 'icon-position',
name: {
'zh-CN': 'icon对齐方式',
'en-US': 'Icon Alignment'
},
desc: {
'zh-CN': '<p>通过 <code>icon-position</code> 属性设置图标与文本的对齐方式。</p>',
'en-US': '<p>Set the alignment of icons and text using the <code>icon-position</code> property.k</p>'
},
codeFiles: ['icon-position.vue']
},
{
demoId: 'event-change',
@ -21,45 +86,10 @@ export default {
'en-US': 'button round'
},
desc: {
'zh-CN': '<p>事件</p>',
'en-US': '<p>button round</p>'
'zh-CN': '<p>勾选值改变后将触发 <code>change</code> 事件</p>',
'en-US': '<p>The <code>change</code> event is triggered when the value of the check box is changed. </p>'
},
codeFiles: ['event-change.vue']
},
{
demoId: 'indeterminate',
name: {
'zh-CN': '全选与半选',
'en-US': 'events'
},
desc: {
'zh-CN': '<p>全选与半选</p>',
'en-US': '<p>bbutton click</p>'
},
codeFiles: ['indeterminate.vue']
},
{
demoId: 'label',
name: {
'zh-CN': '选中值设置',
'en-US': 'events'
},
desc: {
'zh-CN': '<p>复选框组选中的值设置</p>'
},
codeFiles: ['label.vue']
},
{
demoId: 'true-false-label',
name: {
'zh-CN': '选中值设置',
'en-US': 'events'
},
desc: {
'zh-CN': '<p>选中与未选中的值设置</p>',
'en-US': '<p>bbutton click</p>'
},
codeFiles: ['true-false-label.vue']
}
],
apis: [
@ -72,8 +102,8 @@ export default {
type: 'Boolean',
defaultValue: 'false',
desc: {
'zh-CN': '<p>当前是否勾选,该属性默认为false</p>',
'en-US': 'display different button'
'zh-CN': '<p>是否选中</p>',
'en-US': '<p>whether checked</p>'
},
demoId: ''
},
@ -82,20 +112,30 @@ export default {
type: 'Boolean',
defaultValue: 'false',
desc: {
'zh-CN': '<p>当前是否勾选,该属性默认为false</p>',
'en-US': 'display different button'
'zh-CN': '<p>是否禁用</p>',
'en-US': '<p>whether disabled</p>'
},
demoId: 'label'
demoId: 'disabled'
},
{
name: 'false-label',
type: 'String',
defaultValue: '',
desc: {
'zh-CN': '<p>没有选中时的值</p>',
'en-US': 'display different button'
'zh-CN': '<p>未选中的值</p>',
'en-US': '<p>alue when no option is selected</p>'
},
demoId: 'true-false-label'
demoId: 'custom-value'
},
{
name: 'icon-position',
type: 'String',
defaultValue: 'center',
desc: {
'zh-CN': "<p>图标与文本的对齐方式,可选值:'center' | 'top'</p>",
'en-US': "<p>Alignment of icon and text, optional value: 'center' | 'top'</p>"
},
demoId: 'icon-position'
},
{
name: 'true-label',
@ -103,17 +143,18 @@ export default {
defaultValue: '',
desc: {
'zh-CN': '<p>选中时的值</p>',
'en-US': 'display different button'
'en-US': '<p>selected value</p>'
},
demoId: 'true-false-label'
demoId: 'custom-value'
},
{
name: 'indeterminate',
type: 'Boolean',
defaultValue: 'false',
desc: {
'zh-CN': '<p>设置 indeterminate 状态,只负责样式控制,该属性默认为false</p>',
'en-US': 'display different button'
'zh-CN': '<p>设置 indeterminate 状态,只负责样式控制,该属性默认为 false</p>',
'en-US':
'<p>Setting an indeterminate state, which only controls the style, and this property by default is false.</p>'
},
demoId: 'indeterminate'
},
@ -123,9 +164,10 @@ export default {
defaultValue: '',
desc: {
'zh-CN': '<p>选中状态的值只有在checkbox-group或者绑定对象类型为array时有效</p>',
'en-US': 'display different button'
'en-US':
'<p>The value of the selected state (only valid for checkbox-group or when the bound object is of type array)</p>'
},
demoId: 'label'
demoId: 'basic-usage'
},
{
name: 'name',
@ -133,19 +175,19 @@ export default {
defaultValue: '',
desc: {
'zh-CN': '<p>原生 name 属性</p>',
'en-US': 'display different button'
'en-US': '<p>native name attribute.</p>'
},
demoId: 'label'
demoId: ''
},
{
name: 'value / v-model',
name: 'v-model / modelValue',
type: 'String',
defaultValue: '',
desc: {
'zh-CN': '<p>绑定值</p>',
'en-US': 'display different button'
'en-US': '<p>value</p>'
},
demoId: 'default'
demoId: 'basic-usage'
}
],
events: [
@ -155,7 +197,7 @@ export default {
defaultValue: '',
desc: {
'zh-CN': '<p>当绑定值变化时触发的事件,该事件可获取更新后的值</p>',
'en-US': 'Click'
'en-US': '<p>This event is triggered when the binding value changes</p>'
},
demoId: 'event-change'
}
@ -166,8 +208,8 @@ export default {
type: '',
defaultValue: '',
desc: {
'zh-CN': '<p>组件默认插槽</p>',
'en-US': 'Click'
'zh-CN': '<p>标签文本内容</p>',
'en-US': '<p>label content</p>'
},
demoId: ''
}

View File

@ -1,37 +0,0 @@
<template>
<div class="input-wrap">
<tiny-input v-model="input" type="textarea" autosize autofocus placeholder="请输入内容"></tiny-input>
<tiny-input
v-model="input"
type="textarea"
:autosize="{ minRows: 2, maxRows: 3 }"
placeholder="请输入内容"
></tiny-input>
</div>
</template>
<script lang="jsx">
import { Input } from '@opentiny/vue'
export default {
components: {
TinyInput: Input
},
data() {
return {
input: ''
}
}
}
</script>
<style>
.input-wrap {
padding-top: 20px;
height: 100%;
background: #f4f4f4;
}
.input-wrap .tiny-mobile-textarea + .tiny-mobile-textarea {
margin-top: 24px;
}
</style>

View File

@ -1,41 +0,0 @@
<template>
<div class="input-wrap">
<tiny-input
v-model="input"
type="textarea"
autosize
disabled
textarea-title="textarea-title"
placeholder="请输入内容"
></tiny-input>
<tiny-input
v-model="input"
type="textarea"
:autosize="{ minRows: 2, maxRows: 3 }"
placeholder="请输入内容"
></tiny-input>
</div>
</template>
<script lang="jsx">
import { Input } from '@opentiny/vue'
export default {
components: {
TinyInput: Input
},
data() {
return {
input: ''
}
}
}
</script>
<style>
.input-wrap {
padding-top: 20px;
height: 100%;
background: #f4f4f4;
}
</style>

View File

@ -0,0 +1,32 @@
<template>
<div class="demo-input">
<tiny-input v-model="input" :placeholder="placeholder"></tiny-input>
<br />
<tiny-input v-model="textareaVal" type="textarea" placeholder="用作文本框"></tiny-input>
</div>
</template>
<script>
import { Input } from '@opentiny/vue'
export default {
components: {
TinyInput: Input
},
data() {
return {
input: '',
textareaVal: '',
placeholder: '请输入内容'
}
}
}
</script>
<style scoped>
.demo-input {
padding: 20px 16px;
height: 100%;
background: #f5f5f5;
}
</style>

View File

@ -1,40 +0,0 @@
<template>
<div class="input-wrap">
<tiny-button @click="focus">获取焦点</tiny-button>
<tiny-button @click="blur">失去焦点</tiny-button>
<br /><br />
<tiny-input ref="input" v-model="input"></tiny-input>
</div>
</template>
<script lang="jsx">
import { Input, Button } from '@opentiny/vue'
export default {
components: {
TinyInput: Input,
TinyButton: Button
},
data() {
return {
input: ''
}
},
methods: {
focus() {
this.$refs.input.focus()
},
blur() {
this.$refs.input.blur()
}
}
}
</script>
<style>
.input-wrap {
padding-top: 20px;
height: 100%;
background: #f4f4f4;
}
</style>

View File

@ -1,10 +1,10 @@
<template>
<div class="input-wrap">
<div class="demo-input">
<tiny-input v-model="input" clearable></tiny-input>
</div>
</template>
<script lang="jsx">
<script>
import { Input } from '@opentiny/vue'
export default {
@ -13,16 +13,16 @@ export default {
},
data() {
return {
input: '这是输入框'
input: '可一键清空'
}
}
}
</script>
<style>
.input-wrap {
padding-top: 20px;
<style scoped>
.demo-input {
padding: 20px 16px;
height: 100%;
background: #f4f4f4;
background: #f5f5f5;
}
</style>

View File

@ -1,28 +0,0 @@
<template>
<div class="input-wrap">
<tiny-input v-model="input" type="textarea" :cols="5" :rows="1"></tiny-input>
</div>
</template>
<script lang="jsx">
import { Input } from '@opentiny/vue'
export default {
components: {
TinyInput: Input
},
data() {
return {
input: '测试 cols 属性'
}
}
}
</script>
<style>
.input-wrap {
padding-top: 20px;
height: 100%;
background: #f4f4f4;
}
</style>

View File

@ -1,10 +1,12 @@
<template>
<div class="input-wrap">
<tiny-input v-model="input" type="textarea" counter show-word-limit :maxlength="20"></tiny-input>
<div class="demo-input">
<tiny-input v-model="input1" counter :maxlength="20"></tiny-input>
<tiny-input v-model="input2" type="textarea" show-word-limit :maxlength="20"></tiny-input>
</div>
</template>
<script lang="jsx">
<script>
import { Input } from '@opentiny/vue'
export default {
@ -13,16 +15,21 @@ export default {
},
data() {
return {
input: '测试 counter 属性'
input1: 'counter 示例',
input2: 'show-word-limit 示例'
}
}
}
</script>
<style>
.input-wrap {
padding-top: 20px;
<style scoped>
.demo-input {
padding: 20px 16px;
height: 100%;
background: #f4f4f4;
background: #f5f5f5;
}
.demo-input [class^='tiny'] {
margin-bottom: 8px;
}
</style>

View File

@ -0,0 +1,31 @@
<template>
<div class="demo-input">
<tiny-input v-model="input" disabled :placeholder="placeholder"></tiny-input>
<br />
<tiny-input v-model="text" type="textarea" disabled></tiny-input>
</div>
</template>
<script>
import { Input } from '@opentiny/vue'
export default {
components: {
TinyInput: Input
},
data() {
return {
input: '',
text: '已输入值',
placeholder: '请输入内容'
}
}
}
</script>
<style scoped>
.demo-input {
padding: 20px;
height: 100%;
}
</style>

View File

@ -1,11 +1,14 @@
<template>
<div class="input-wrap">
<tiny-input v-model="input" clearable @change="change" @clear="clear"></tiny-input>
<div class="demo-input-events">
<tiny-input v-model="inputValue" placeholder="input" @input="onInput"></tiny-input>
<tiny-input v-model="inputChange" placeholder="change" @change="onChange"></tiny-input>
<tiny-input v-model="focusBlur" placeholder="focus, blur" @focus="onFocus" @blur="onBlur"></tiny-input>
<tiny-input v-model="clearValue" placeholder="cleared" clearable @clear="onClear"></tiny-input>
</div>
</template>
<script lang="jsx">
import { Input } from '@opentiny/vue'
<script>
import { Input, Modal } from '@opentiny/vue'
export default {
components: {
@ -13,24 +16,40 @@ export default {
},
data() {
return {
input: '事件测试'
inputValue: '',
inputChange: '',
focusBlur: '',
clearValue: 'clear event'
}
},
methods: {
change(val) {
console.log('当前内容:' + val)
onChange() {
Modal.message('change')
},
clear() {
console.log('clear 事件')
onInput() {
Modal.message('input')
},
onBlur() {
Modal.message('blur')
},
onFocus() {
Modal.message('focus')
},
onClear() {
Modal.message('clear')
}
}
}
</script>
<style>
.input-wrap {
padding-top: 20px;
<style scoped>
.demo-input-events {
height: 100%;
background: #f4f4f4;
padding: 20px 16px;
background: #f5f5f5;
}
.demo-input-events [class^='tiny'] {
margin-bottom: 16px;
}
</style>

View File

@ -1,45 +0,0 @@
<template>
<div class="input-wrap">
<tiny-input v-model="input" type="form" is-select :select-menu="selectMenu" placeholder="下拉功能"></tiny-input>
</div>
</template>
<script lang="jsx">
import { Input } from '@opentiny/vue'
export default {
components: {
TinyInput: Input
},
data() {
return {
selectMenu: [
{
label: '黄金糕'
},
{
label: '双皮奶'
},
{
label: '蚵仔煎'
},
{
label: '龙须面'
},
{
label: '北京烤鸭'
}
],
input: ''
}
}
}
</script>
<style>
.input-wrap {
padding-top: 20px;
height: 100%;
background: #f4f4f4;
}
</style>

View File

@ -1,39 +0,0 @@
<template>
<div class="input-wrap">
<tiny-input v-model="value" clearable @blur="blur" @focus="focus" @input="input"></tiny-input>
</div>
</template>
<script lang="jsx">
import { Input } from '@opentiny/vue'
export default {
components: {
TinyInput: Input
},
data() {
return {
value: '事件测试'
}
},
methods: {
blur() {
console.log('blur 事件')
},
focus() {
console.log('focus 事件')
},
input(value) {
console.log('input' + value)
}
}
}
</script>
<style>
.input-wrap {
padding-top: 20px;
height: 100%;
background: #f4f4f4;
}
</style>

View File

@ -1,10 +1,10 @@
<template>
<div class="input-wrap">
<div class="demo-input">
<tiny-input v-model="input" counter :maxlength="10" :minlength="5"></tiny-input>
</div>
</template>
<script lang="jsx">
<script>
import { Input } from '@opentiny/vue'
export default {
@ -19,10 +19,10 @@ export default {
}
</script>
<style>
.input-wrap {
<style scoped>
.demo-input {
padding-top: 20px;
height: 100%;
background: #f4f4f4;
background: #f5f5f5;
}
</style>

View File

@ -1,36 +0,0 @@
<template>
<div class="input-wrap">
<tiny-button @click="click">选中输入框内容</tiny-button>
<br /><br />
<tiny-input ref="input" v-model="input"></tiny-input>
</div>
</template>
<script lang="jsx">
import { Input, Button } from '@opentiny/vue'
export default {
components: {
TinyInput: Input,
TinyButton: Button
},
data() {
return {
input: '我是输入框'
}
},
methods: {
click() {
this.$refs.input.select()
}
}
}
</script>
<style>
.input-wrap {
padding-top: 20px;
height: 100%;
background: #f4f4f4;
}
</style>

View File

@ -0,0 +1,53 @@
<template>
<div class="demo-input-methods">
<section>
<tiny-button plain @click="focus">focus</tiny-button>
<tiny-button plain @click="blur">blur</tiny-button>
<tiny-input ref="inputRef" v-model="value" placeholder="Please input"></tiny-input>
</section>
<section>
<tiny-button plain @click="select">select</tiny-button>
<tiny-input ref="selectRef" v-model="selectValue" placeholder="Please input"></tiny-input>
</section>
</div>
</template>
<script>
import { Input, Button } from '@opentiny/vue'
export default {
components: {
TinyInput: Input,
TinyButton: Button
},
data() {
return {
value: '',
selectValue: '123456'
}
},
methods: {
select() {
this.$refs.selectRef.select()
},
blur() {
this.$refs.inputRef.blur()
},
focus() {
this.$refs.inputRef.focus()
}
}
}
</script>
<style scoped>
.demo-input-methods {
height: 100%;
padding: 20px 16px;
background: #f5f5f5;
}
.demo-input-methods [class^='tiny'] {
margin: 5px;
}
</style>

View File

@ -0,0 +1,62 @@
<template>
<div class="demo-input">
<div class="demo-input-item">
<span>autofocus</span>
<tiny-input v-model="autofocusVal" autofocus></tiny-input>
</div>
<div class="demo-input-item">
<span>readonly</span>
<tiny-input v-model="input" readonly></tiny-input>
</div>
<div class="demo-input-item">
<span>autocomplete="on"</span>
<form>
<tiny-input v-model="inputAutocomplete" autocomplete="on" name="email" type="email"></tiny-input>
</form>
</div>
<div class="demo-input-item">
<span>step=2</span>
<tiny-input type="number" v-model="inputStep" :step="2" placeholder="step 为 2"></tiny-input>
</div>
<div class="demo-input-item">
<span>min=2; max=11</span>
<tiny-input type="number" v-model="inputMaxMin" :min="2" :max="11"></tiny-input>
</div>
<div class="demo-input-item">
<span>name</span>
<tiny-input v-model="username" name="username"></tiny-input>
</div>
</div>
</template>
<script>
import { Input } from '@opentiny/vue'
export default {
components: {
TinyInput: Input
},
data() {
return {
autofocusVal: '',
input: 'readonly',
inputStep: 2,
inputMaxMin: 1,
inputAutocomplete: '',
username: ''
}
}
}
</script>
<style scoped>
.demo-input {
padding: 20px 16px;
height: 100%;
background: #f5f5f5;
}
.demo-input .demo-input-item {
margin-bottom: 12px;
}
</style>

View File

@ -0,0 +1,35 @@
<template>
<div class="demo-input-icons">
<tiny-input v-model="value" :prefix-icon="IconSearch" placeholder="前置图标示例"></tiny-input>
<tiny-input v-model="value" :suffix-icon="IconSearch" placeholder="后置图标示例"></tiny-input>
</div>
</template>
<script>
import { Input } from '@opentiny/vue'
import { iconSearch } from '@opentiny/vue-icon'
export default {
components: {
TinyInput: Input
},
data() {
return {
value: '',
IconSearch: iconSearch()
}
}
}
</script>
<style scoped>
.demo-input-icons {
height: 100%;
padding: 20px 16px;
background: #f5f5f5;
}
.demo-input-icons .tiny-mobile-input {
margin-bottom: 16px;
}
</style>

View File

@ -1,39 +0,0 @@
<template>
<div class="input-wrap">
<tiny-input placeholder="请输入内容" v-model="input">
<template #prefix>
<div style="color: red">Http</div>
</template>
<template #suffix>
<div style="color: red">com</div>
</template>
</tiny-input>
</div>
</template>
<script lang="jsx">
import { Input } from '@opentiny/vue'
export default {
components: {
TinyInput: Input
},
data() {
return {
input: ''
}
}
}
</script>
<style>
.input-wrap {
padding-top: 20px;
height: 100%;
background: #f4f4f4;
}
.tiny-mobile-input-prefix .tiny-mobile-input__inner {
padding-left: 45px;
padding-right: 28px;
}
</style>

View File

@ -1,28 +0,0 @@
<template>
<div class="input-wrap">
<tiny-input v-model="input" type="number" step="3" placeholder="当前步长为3"></tiny-input>
</div>
</template>
<script lang="jsx">
import { Input } from '@opentiny/vue'
export default {
components: {
TinyInput: Input
},
data() {
return {
input: '测试长度'
}
}
}
</script>
<style>
.input-wrap {
padding-top: 20px;
height: 100%;
background: #f4f4f4;
}
</style>

View File

@ -1,28 +0,0 @@
<template>
<div class="input-wrap">
<tiny-input v-model="input" name="name" label="label" readonly></tiny-input>
</div>
</template>
<script lang="jsx">
import { Input } from '@opentiny/vue'
export default {
components: {
TinyInput: Input
},
data() {
return {
input: '测试长度'
}
}
}
</script>
<style>
.input-wrap {
padding-top: 20px;
height: 100%;
background: #f4f4f4;
}
</style>

View File

@ -1,5 +1,5 @@
<template>
<div class="input-wrap">
<div class="demo-input">
<tiny-input v-model="input" show-password></tiny-input>
</div>
</template>
@ -19,10 +19,10 @@ export default {
}
</script>
<style>
.input-wrap {
padding-top: 20px;
<style scoped>
.demo-input {
height: 100%;
background: #f4f4f4;
padding: 20px 16px;
background: #f5f5f5;
}
</style>

View File

@ -1,30 +0,0 @@
<template>
<div class="input-wrap">
<tiny-input v-model="input" type="textarea">
<template #content> 自定义头部内容 </template>
</tiny-input>
</div>
</template>
<script lang="jsx">
import { Input } from '@opentiny/vue'
export default {
components: {
TinyInput: Input
},
data() {
return {
input: ''
}
}
}
</script>
<style>
.input-wrap {
padding-top: 20px;
height: 100%;
background: #f4f4f4;
}
</style>

View File

@ -1,34 +0,0 @@
<template>
<div class="input-wrap">
<tiny-input placeholder="请输入内容" v-model="input">
<template #prepend>Http://</template>
</tiny-input>
<br /><br />
<tiny-input placeholder="请输入内容" v-model="input">
<template #append>.com</template>
</tiny-input>
</div>
</template>
<script lang="jsx">
import { Input } from '@opentiny/vue'
export default {
components: {
TinyInput: Input
},
data() {
return {
input: ''
}
}
}
</script>
<style>
.input-wrap {
padding-top: 20px;
height: 100%;
background: #f4f4f4;
}
</style>

View File

@ -0,0 +1,65 @@
<template>
<div class="demo-input">
<tiny-input placeholder="prepend" v-model="input">
<template #prepend>Http://</template>
</tiny-input>
<tiny-input placeholder="append" v-model="input">
<template #append>.com</template>
</tiny-input>
<tiny-input placeholder="prefix" v-model="input">
<template #prefix>
<tiny-icon-search/>
</template>
</tiny-input>
<tiny-input placeholder="suffix" v-model="input">
<template #suffix>
<tiny-icon-calendar/>
</template>
</tiny-input>
<br />
<tiny-input placeholder="suffix" v-model="input">
<template #title>
<span>标题插槽内容</span>
</template>
<template #tips>
<span class="tips">提示插槽内容</span>
</template>
</tiny-input>
</div>
</template>
<script>
import { Input } from '@opentiny/vue'
import { IconSearch, IconCalendar } from '@opentiny/vue-icon'
export default {
components: {
TinyInput: Input,
TinyIconSearch: IconSearch(),
TinyIconCalendar: IconCalendar(),
},
data() {
return {
input: ''
}
}
}
</script>
<style scoped>
.demo-input {
height: 100%;
padding: 20px 16px;
background: #f5f5f5;
}
.demo-input [class^=tiny-mobile] {
margin-bottom: 8px;
}
.tips {
color: #f23030;
}
</style>

View File

@ -1,30 +0,0 @@
<template>
<div class="input-wrap">
<tiny-input v-model="input" placeholder="请输入内容" :suffix-icon="IconDialog"></tiny-input>
</div>
</template>
<script lang="jsx">
import { Input } from '@opentiny/vue'
import { iconDialog } from '@opentiny/vue-icon'
export default {
components: {
TinyInput: Input
},
data() {
return {
input: '',
IconDialog: iconDialog()
}
}
}
</script>
<style>
.input-wrap {
padding-top: 20px;
height: 100%;
background: #f4f4f4;
}
</style>

View File

@ -0,0 +1,31 @@
<template>
<div class="demo-input">
<p>rows=3 cols=80</p>
<tiny-input type="textarea" v-model="value" :rows="rows" :cols="cols" ></tiny-input>
</div>
</template>
<script>
import { Input } from '@opentiny/vue'
export default {
components: {
TinyInput: Input
},
data() {
return {
value: '杭州西湖是我国著名的旅游胜地,其位于浙江省杭州市西部。西湖是中国最美丽的湖泊之一。',
rows: 3,
cols: 30,
}
}
}
</script>
<style scoped>
.demo-input {
height: 100%;
padding: 20px 16px;
background: #f5f5f5;
}
</style>

View File

@ -0,0 +1,41 @@
<template>
<div class="demo-input">
<p>resize</p>
<tiny-input type="textarea" v-model="input" resize="vertical" placeholder="resize = vertical (default)"></tiny-input>
<tiny-input type="textarea" v-model="input" resize="none" placeholder="resize = none"></tiny-input>
<tiny-input type="textarea" v-model="input" resize="both" placeholder="resize = both" width="300px"></tiny-input>
<tiny-input type="textarea" v-model="input" resize="horizontal" placeholder="resize = horizontal"></tiny-input>
<p>autosize</p>
<tiny-input type="textarea" v-model="textarea" placeholder="autosize" autosize></tiny-input>
<tiny-input type="textarea" v-model="textarea" placeholder="autosize = { minRows: 2, maxRows: 3 }" :autosize="{ minRows: 2, maxRows: 3 }"></tiny-input>
</div>
</template>
<script>
import { Input } from '@opentiny/vue'
export default {
components: {
TinyInput: Input
},
data() {
return {
input: '',
textarea: ''
}
}
}
</script>
<style scoped>
.demo-input {
height: 100%;
padding: 20px 16px;
background: #f5f5f5;
}
.demo-input .tiny-mobile-textarea {
margin-bottom: 8px;
}
</style>

View File

@ -1,55 +0,0 @@
<template>
<div class="input-wrap">
<tiny-input
v-model="input"
mobile-tips="让你输入一段文字"
is-select
:select-menu="menus"
placeholder="请输入内容"
type="form"
mobileTips="曾经有一段真挚的感情"
></tiny-input>
</div>
</template>
<script lang="jsx">
import { Input } from '@opentiny/vue'
export default {
components: {
TinyInput: Input
},
data() {
return {
input: 'hello mobile',
menus: [
{
id: 1,
label: '我是小花,我是小花,我是小花,我是小花,我是小花,我是小花,我是小花'
},
{
id: 2,
label: '我是小树'
},
{
id: 3,
label: '我是小草'
},
{
id: 4,
label: '我是小叶',
warn: true
}
]
}
}
}
</script>
<style>
.input-wrap {
padding-top: 20px;
height: 100%;
background: #f4f4f4;
}
</style>

View File

@ -1,47 +0,0 @@
<template>
<div class="input-wrap">
<tiny-input v-model="input" placeholder="请输入内容" type="form"></tiny-input>
</div>
</template>
<script lang="jsx">
import { Input } from '@opentiny/vue'
export default {
components: {
TinyInput: Input
},
data() {
return {
input: 'hello mobile',
menus: [
{
id: 1,
label: '我是小花,我是小花,我是小花,我是小花,我是小花,我是小花,我是小花'
},
{
id: 2,
label: '我是小树'
},
{
id: 3,
label: '我是小草'
},
{
id: 4,
label: '我是小叶',
warn: true
}
]
}
}
}
</script>
<style>
.input-wrap {
padding-top: 20px;
height: 100%;
background: #f4f4f4;
}
</style>

View File

@ -1,10 +1,10 @@
<template>
<div class="input-wrap">
<div class="demo-input">
<tiny-input v-model="input" is-select :select-menu="menus" placeholder="请输入内容" type="form"></tiny-input>
</div>
</template>
<script lang="jsx">
<script>
import { Input } from '@opentiny/vue'
export default {
@ -17,19 +17,19 @@ export default {
menus: [
{
id: 1,
label: '我是小花,我是小花,我是小花,我是小花,我是小花,我是小花,我是小花'
label: '很长的选项。很长的选项。很长的选项。很长的选项。很长的选项。很长的选项。很长的选项。'
},
{
id: 2,
label: '我是小树'
label: '选项2'
},
{
id: 3,
label: '我是小草'
label: '选项3'
},
{
id: 4,
label: '我是小叶',
label: 'warn 为true的选项',
warn: true
}
]
@ -38,10 +38,10 @@ export default {
}
</script>
<style>
.input-wrap {
padding-top: 20px;
<style scoped>
.demo-input {
padding: 20px 16px;
height: 100%;
background: #f4f4f4;
background: #f5f5f5;
}
</style>

View File

@ -0,0 +1,60 @@
<template>
<div class="demo-input">
<tiny-input v-model="text" placeholder="text"></tiny-input>
<tiny-input type="password" v-model="password" placeholder="password"></tiny-input>
<tiny-input type="textarea" v-model="textarea" placeholder="textarea"></tiny-input>
<tiny-input type="email" v-model="email" placeholder="email"></tiny-input>
<tiny-input type="number" v-model="number" placeholder="number"></tiny-input>
<tiny-input type="tel" v-model="tel" placeholder="tel"></tiny-input>
<tiny-input type="url" v-model="url" placeholder="url"></tiny-input>
<tiny-input type="date" v-model="date"></tiny-input>
<tiny-input type="month" v-model="month"></tiny-input>
<tiny-input type="week" v-model="week"></tiny-input>
<tiny-input type="datetime-local" v-model="datetime"></tiny-input>
<tiny-input type="time" v-model="time"></tiny-input>
</div>
</template>
<script>
import { Input } from '@opentiny/vue'
export default {
components: {
TinyInput: Input
},
data() {
return {
text: '',
password: '',
textarea: '',
email: '',
number: '',
tel: '',
url: '',
color: '#000000',
date: '',
month: '',
week: '',
datetime: '',
time: '',
file: '',
range: ''
}
}
}
</script>
<style scoped>
.demo-input {
height: 100%;
padding: 20px 16px;
box-sizing: border-box;
overflow-y: scroll;
background: #f5f5f5;
}
.demo-input .tiny-mobile-input,
.demo-input .tiny-mobile-textarea {
margin-bottom: 8px;
}
</style>

View File

@ -1,5 +1,5 @@
<template>
<div class="input-wrap event-validate-demo1">
<div class="demo-input">
<div class="page__hd">
<tiny-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-form">
<tiny-form-item label="活动名称" prop="name">
@ -10,7 +10,7 @@
</div>
</template>
<script lang="jsx">
<script>
import { Input, Form, FormItem } from '@opentiny/vue'
export default {
@ -35,34 +35,9 @@ export default {
}
</script>
<style>
.page__hd {
padding: 40px;
}
.page__title {
font-weight: 400;
font-size: 21px;
text-align: left;
}
.page__desc {
margin-top: 5px;
color: #888;
font-size: 14px;
text-align: left;
}
.page__text {
padding-right: 16px;
padding-left: 16px;
margin-top: 0.77em;
margin-bottom: 0.3em;
color: #666;
font-size: 14px;
}
.input-wrap {
<style scoped>
.demo-input {
height: 100%;
background: #f4f4f4;
}
.event-validate-demo1 .tiny-mobile-input__inner {
margin-left: 85px;
background: #f5f5f5;
}
</style>

View File

@ -3,265 +3,207 @@ export default {
owner: '',
demos: [
{
demoId: 'autofocus',
demoId: 'basic-usage',
name: {
'zh-CN': '自动获取焦点',
'en-US': 'button type'
'zh-CN': '基本用法',
'en-US': 'basic usage'
},
desc: {
'zh-CN': '<p>自动获取焦点</p>',
'en-US': '<p>button type</p>'
'zh-CN':
'<p>通过 <code>v-model/modelValue</code> 属性绑定输入值,<code>placeholder</code> 属性显示提示文本;使用原生属性 <code>type</code> 指定输入框类型,如取值为 <code>textarea</code> 时用作文本框。</p>',
'en-US':
'<p>Bind the input value through the <code>v-model/modelValue</code> property, and use <code>placeholder</code> to bind placeholder.Specify the input box type with the native <code>type</code> attribute. When the value is set to <code>textarea</code>, it is used as a textarea.</p>'
},
codeFiles: ['autofocus.vue']
codeFiles: ['basic-usage.vue']
},
{
demoId: 'autosize',
name: {
'zh-CN': '自适应内容高度',
'en-US': 'button round'
'demoId': 'clearable',
'name': { 'zh-CN': '一键清空', 'en-US': 'Clearable' },
'desc': {
'zh-CN': '<p>可通过 <code>clearable</code> 属性设置输入框显示清空图标按钮。</p>',
'en-US':
'<p>You can set the <code>clearable</code> attribute to display the clear icon button in the input.</p>'
},
desc: {
'zh-CN': '<p>自适应内容高度</p>',
'en-US': '<p>button round</p>'
},
codeFiles: ['autosize.vue']
'codeFiles': ['clearable.vue']
},
{
demoId: 'blur-focus',
demoId: 'type',
name: {
'zh-CN': '获取/失去焦点',
'en-US': 'events'
'zh-CN': '类型',
'en-US': 'type'
},
desc: {
'zh-CN': '<p>获取/失去焦点</p>',
'en-US': '<p>bbutton click</p>'
'zh-CN':
'<p>通过对应的 <code>type</code> 属性,可以设置为对应的类型。默认为 text可选值为 texttextarea 和其他 原生 input 的 type 值</p>',
'en-US':
'<p>You can set the corresponding type through the corresponding <code>type</code> attribute. The default value is text. The options are text, textarea, and other type values of the native input</p>'
},
codeFiles: ['blur-focus.vue']
codeFiles: ['type.vue']
},
{
demoId: 'clearable',
demoId: 'textarea-rows-cols',
name: {
'zh-CN': '可清空',
'en-US': 'events'
'zh-CN': '文本框行数与列数',
'en-US': 'Rows and Columns of Textarea'
},
desc: {
'zh-CN': '<p>可清空</p>'
'zh-CN': '<p>通过原生属性 <code>rows</code> 与 <code>cols</code> 分别指定文本框的行数与列字符数。</p>',
'en-US':
'<p>Specify the number of rows and columns of a text box using the native attributes <code>rows</code> and <code>cols</code> respectively.</p>'
},
codeFiles: ['clearable.vue']
codeFiles: ['textarea-rows-cols.vue']
},
{
demoId: 'cols-rows',
demoId: 'textarea-scalable',
name: {
'zh-CN': '原生属性',
'en-US': 'events'
'zh-CN': '文本框可缩放',
'en-US': 'Scalable Textarea'
},
desc: {
'zh-CN': '<p>宽度和高度</p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': `<p>可通过 <code>resize</code> 属性设置文本框的缩放。可选值:<code>none | both | horizontal | vertical</code>。</p><p>可通过 <code>autosize</code> 属性设置文本框自适应内容高度。可传入对象,如 <code>{ minRows: 2, maxRows: 6 }</code>。`,
'en-US': `<p>You can use the <code>resize</code> property to set the zoom of the text field. The value can be <code>none | both | horizontal | vertical</code> . Note: This parameter is valid only when <code>type="textarea"</code> is used. </p>
<p>You can use the <code>autosize</code> attribute to set the text field to adapt to the content height. You can transfer an object, for example, <code>{minRows: 2, maxRows: 6}</code> . Note: This parameter is valid only for <code>type="textarea"</code> . </p>`
},
codeFiles: ['cols-rows.vue']
},
{
demoId: 'counter',
name: {
'zh-CN': '计数与输入统计',
'en-US': 'events'
},
desc: {
'zh-CN': '<p>计数与输入统计</p>',
'en-US': '<p>bbutton click</p>'
},
codeFiles: ['counter.vue']
},
{
demoId: 'events',
name: {
'zh-CN': '事件',
'en-US': 'events'
},
desc: {
'zh-CN': '<p>事件</p>',
'en-US': '<p>bbutton click</p>'
},
codeFiles: ['events.vue']
},
{
demoId: 'form',
name: {
'zh-CN': 'form',
'en-US': 'events'
},
desc: {
'zh-CN': '<p>form</p>',
'en-US': '<p>bbutton click</p>'
},
codeFiles: ['form.vue']
},
{
demoId: 'input-event',
name: {
'zh-CN': '事件',
'en-US': 'events'
},
desc: {
'zh-CN': '<p>blur / focus / input 事件</p>',
'en-US': '<p>bbutton click</p>'
},
codeFiles: ['input-event.vue']
},
{
demoId: 'max-min-length',
name: {
'zh-CN': '输入长度限制',
'en-US': 'events'
},
desc: {
'zh-CN': '<p>输入长度限制</p>',
'en-US': '<p>bbutton click</p>'
},
codeFiles: ['max-min-length.vue']
},
{
demoId: 'method-select',
name: {
'zh-CN': '选中输入框文本',
'en-US': 'events'
},
desc: {
'zh-CN': '<p>选中输入框文本</p>',
'en-US': '<p>bbutton click</p>'
},
codeFiles: ['method-select.vue']
},
{
demoId: 'prefix-suffix',
name: {
'zh-CN': '复合型输入框',
'en-US': 'events'
},
desc: {
'zh-CN': '<p>复合型输入框</p>',
'en-US': '<p>bbutton click</p>'
},
codeFiles: ['prefix-suffix.vue']
},
{
demoId: 'props-step',
name: {
'zh-CN': '步长',
'en-US': 'events'
},
desc: {
'zh-CN': '<p>通过<code>step</code>设置步长,需要结合 type="number" 一起使用</p>',
'en-US': '<p>bbutton click</p>'
},
codeFiles: ['props-step.vue']
},
{
demoId: 'props',
name: {
'zh-CN': '原生属性',
'en-US': 'events'
},
desc: {
'zh-CN': '<p>是否只读</p>',
'en-US': '<p>bbutton click</p>'
},
codeFiles: ['props.vue']
codeFiles: ['textarea-scalable.vue']
},
{
demoId: 'show-password',
name: {
'zh-CN': '密码框',
'en-US': 'events'
'en-US': 'Password Input'
},
desc: {
'zh-CN': '<p>密码框</p>',
'en-US': '<p>bbutton click</p>'
'zh-CN':
'<p>当 <code>type</code> 为 <code>password</code> 时,可通过 <code>show-password</code> 属性设置输入框显示密码显示/隐藏切换图标按钮。</p>',
'en-US':
'<p>When <code>type</code> is set to <code>password</code>, you can set the <code>show-password</code> attribute to display or hide the password switch button in the text box.</p>'
},
codeFiles: ['show-password.vue']
},
{
demoId: 'slot-content',
demoId: 'disabled',
name: {
'zh-CN': '禁用',
'en-US': 'disabled'
},
desc: {
'zh-CN': '<p>通过 <code>code</code> 属性禁用输入框。</p>',
'en-US': '<p>To disabled input through <code>code</code> props.</p>'
},
codeFiles: ['disabled.vue']
},
{
demoId: 'counter',
name: {
'zh-CN': '输入长度限制与计数',
'en-US': 'Input Limitation and Counting'
},
desc: {
'zh-CN':
'<p>通过 <code>maxlength</code> 属性限制输入字符数; <code>counter</code> 属性显示当前输入字符数;<code>show-word-limit</code> 显示当前字符数与输入限制长度(仅限文本框)</p>',
'en-US':
'<p>Limit input character count with the <code>maxlength</code> attribute; display current input character count with the <code>counter</code> attribute; show current character count and input limit length with the <code>show-word-limit</code> attribute(for text boxes only)."</p>'
},
codeFiles: ['counter.vue']
},
{
demoId: 'prefix-suffix-icon',
name: { 'zh-CN': '图标', 'en-US': 'Icon' },
desc: {
'zh-CN': '<p>可通过 <code>prefix-icon, suffix-icon</code> 属性设置输入框头部、尾部图标</p>',
'en-US':
'<p>You can set the header icon or the end icon of the text box through the <code>prefix-icon, suffix-icon</code> attribute </p>'
},
codeFiles: ['prefix-suffix-icon.vue']
},
{
demoId: 'native-attributes',
name: {
'zh-CN': '原生属性',
'en-US': 'Native Attributes'
},
desc: {
'zh-CN': '<p>可设置 <code>autofocus</code>、<code>readonly</code>、<code>name</code> 等原生属性。</p>',
'en-US': '<p>Set native attributes such as autofocus, readonly, name, etc.</p>'
},
codeFiles: ['native-attributes.vue']
},
{
demoId: 'methods',
name: {
'zh-CN': '实例方法',
'en-US': 'Methods'
},
desc: {
'zh-CN': '<p>可使用组件的实例方法:<code>focus | blur | select</code></p>',
'en-US': '<p>Those instance methods available: <code>focus | blur | select</code></p>'
},
codeFiles: ['methods.vue']
},
{
demoId: 'events',
name: {
'zh-CN': '事件',
'en-US': 'Events'
},
desc: {
'zh-CN': `
<p>输入框的事件包括
<code>input</code>(),
<code>blur</code>(),
<code>focus</code>(),
<code>change</code>(),
<code>clear</code>()
</p>
`,
'en-US': `
<p>Event of the text box, including:
<code>input</code> (triggered when a value is entered)
<code>blur</code> (triggered when the focus is lost)
<code>focus</code> (triggered when the focus is obtained)
<code>change</code> (triggered when the value changes)
<code>clear</code> (triggered when the button is cleared)
</p>
`
},
codeFiles: ['events.vue']
},
{
demoId: 'slots',
name: {
'zh-CN': '插槽',
'en-US': 'events'
},
desc: {
'zh-CN': '<p>通过<code>content</code>自定义头部内容,只对 type="textarea" 有效</p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>Input 组件提供了丰富的插槽。</p>',
'en-US': '<p>Input component provides a rich set of slots.</p>'
},
codeFiles: ['slot-content.vue']
codeFiles: ['slots.vue']
},
{
demoId: 'slots-append-prepend',
demoId: 'type-select',
name: {
'zh-CN': '复合型输入框',
'zh-CN': '下拉列表',
'en-US': 'events'
},
desc: {
'zh-CN': '<p>通过<code>append</code>自定义头部内容,通过 <code>prepend</code>自定义尾部内容,</p>',
'en-US': '<p>bbutton click</p>'
'zh-CN': '<p>通过使用 <code>is-select</code> 与 <code>select-menu</code> 搭配让输入框变为下拉列表。</p>',
'en-US':
'<p>By using <code>is-select</code> with <code>select-menu</code>, the input field can be turned into a dropdown list.</p>'
},
codeFiles: ['slots-append-prepend.vue']
},
{
demoId: 'suffix-icon',
name: {
'zh-CN': '自定义后置图标',
'en-US': 'events'
},
desc: {
'zh-CN': '<p>自定义后置图标</p>',
'en-US': '<p>bbutton click</p>'
},
codeFiles: ['suffix-icon.vue']
},
{
demoId: 'type-be-form-select',
name: {
'zh-CN': '类型<code>type</code>为 form 时的下拉用法',
'en-US': 'events'
},
desc: {
'zh-CN': '<p><code>is-select</code>与<code>select-menu</code>搭配让<code>type</code>为form的输入框变为下拉</p>',
'en-US': '<p>bbutton click</p>'
},
codeFiles: ['type-be-form-select.vue']
},
{
demoId: 'type-be-form-tips',
name: {
'zh-CN': 'form类型的文字提示',
'en-US': 'events'
},
desc: {
'zh-CN': '<p>类型<code>type<code>为 form 时的输入框下的提示</p>',
'en-US': '<p>bbutton click</p>'
},
codeFiles: ['type-be-form-tips.vue']
},
{
demoId: 'type-be-form',
name: {
'zh-CN': 'type为form类型',
'en-US': 'events'
},
desc: {
'zh-CN': '<p>类型<code>type</code>为 form 时的基本用法</p>',
'en-US': '<p>bbutton click</p>'
},
codeFiles: ['type-be-form.vue']
codeFiles: ['type-select.vue']
},
{
demoId: 'validate-event',
name: {
'zh-CN': '表单校正',
'en-US': 'events'
'zh-CN': '表单校验',
'en-US': 'form validation'
},
desc: {
'zh-CN': '<p>通过<code>validate-event</code>属性设置输入时是否触发表单的校验,该属性默认为 true。</p>',
'en-US': '<p>bbutton click</p>'
'zh-CN':
'<p>可通过 <code>validate-event</code> 属性设置输入时触发表单校验。通过 <code>trigger</code> 配置触发校验规则的方式,为 <code>change</code> 时,当输入框值改变即触发校验,为 <code>blur</code> 时则失焦后触发校验</p>',
'en-US':
'<p>You can set the <code>validate-event</code> attribute to trigger form validation upon input. Use <code>trigger</code> to configure the mode of triggering the validation rule. If <code>change</code> is used, the validation is triggered when the value in the text box changes. If <code>blur</code> is used, the validation is triggered after the focus is lost</p>'
},
codeFiles: ['validate-event.vue']
}
@ -276,39 +218,40 @@ export default {
type: 'String',
defaultValue: 'off',
desc: {
'zh-CN': '<p>原生属性,自动补全该属性默认为off</p>',
'en-US': 'display different button'
'zh-CN': '原生属性,自动补全',
'en-US': 'Native autocomplete attribute'
},
demoId: ''
demoId: 'native-attributes'
},
{
name: 'autofocus',
type: 'Boolean',
defaultValue: 'false',
desc: {
'zh-CN': '<p>原生属性,自动获取焦点该属性默认为false</p>',
'en-US': 'display different button'
'zh-CN': '原生属性,自动获取焦点',
'en-US': 'Native attribute. The focus is automatically obtained during page loading.'
},
demoId: 'autofocus'
demoId: 'native-attributes'
},
{
name: 'autosize',
type: 'Boolean | Object',
defaultValue: 'false',
desc: {
'zh-CN':
'<p>自适应内容高度,只对 type="textarea"有效,可传入对象,如,{ minRows: 2, maxRows: 6 }该属性默认为false</p>',
'en-US': 'display different button'
'zh-CN': '自适应内容高度,只对 type="textarea"有效。可传入对象,如,{ minRows: 2, maxRows: 6 }',
'en-US':
'Adaptive content height. This parameter is valid only for <code>type="textarea"</code>. Objects can be transferred, for example, { minRows: 2, maxRows: 6 }'
},
demoId: 'autosize'
demoId: 'textarea-scalable'
},
{
name: 'clearable',
type: 'Boolean',
defaultValue: 'false',
desc: {
'zh-CN': '<p>选中时的值</p>',
'en-US': 'display different button'
'zh-CN': '是否显示清除按钮,该属性不适用于 <code>type="textarea"</code>',
'en-US':
'Whether to display the clear button. This attribute is not applicable to <code>type="textarea"</code>'
},
demoId: 'clearable'
},
@ -317,18 +260,20 @@ export default {
type: 'Number',
defaultValue: '',
desc: {
'zh-CN': '<p>原生属性,设置宽度,在 type ="textarea"时有效</p>',
'en-US': 'display different button'
'zh-CN': '原生属性,设置宽度,在 type ="textarea"时有效',
'en-US':
'Native attribute, which is used to set the width. This parameter is valid only when type is "textarea"'
},
demoId: 'cols-rows'
demoId: 'textarea-rows-cols'
},
{
name: 'counter',
type: 'Boolean',
defaultValue: 'false',
desc: {
'zh-CN': '<p>是否显示字数统计,只在 type = "text" 或 type = "textarea" 时有效</p>',
'en-US': 'display different button'
'zh-CN': '是否显示字数统计,只在 type = "text" 或 type = "textarea" 时有效',
'en-US':
'Whether to display the word count statistics. This parameter is valid only when type is "text" or type is "textarea"'
},
demoId: 'counter'
},
@ -337,128 +282,148 @@ export default {
type: 'Boolean',
defaultValue: 'false',
desc: {
'zh-CN': '<p>禁用该属性默认为false性</p>',
'en-US': 'display different button'
'zh-CN': '是否禁用',
'en-US': 'Disabled'
},
demoId: 'autosize'
},
{
name: 'form',
type: 'String',
defaultValue: '',
desc: {
'zh-CN': '<p>原生属性</p>',
'en-US': 'display different button'
},
demoId: ''
demoId: 'disabled'
},
{
name: 'is-select',
type: 'Boolean',
defaultValue: 'false',
desc: {
'zh-CN': '<p>type为form时设置输入框可下拉选择</p>',
'zh-CN': '是否可下拉选择',
'en-US': 'display different button'
},
demoId: 'type-be-form-select'
demoId: 'type-select'
},
{
name: 'label',
type: 'String',
defaultValue: '',
desc: {
'zh-CN': '<p>输入框关联的label文字</p>',
'en-US': 'display different button'
'zh-CN': '等价于原生 aria-label 属性',
'en-US': 'equal to aria-label attribute'
},
demoId: 'props'
demoId: ''
},
{
name: 'max',
type: 'number',
defaultValue: '',
desc: {
'zh-CN': '原生属性,设置最大值',
'en-US': 'Native attribute, set the maximum value'
},
demoId: 'native-attributes'
},
{
name: 'maxlength',
type: 'Number',
defaultValue: '',
desc: {
'zh-CN': '<p>原生属性,最大输入长度</p>',
'en-US': 'display different button'
'zh-CN': '原生属性,最大输入长度',
'en-US': 'Native attribute, maximum input length'
},
demoId: 'max-min-length'
demoId: 'counter'
},
{
name: 'min',
type: 'number',
defaultValue: '',
desc: {
'zh-CN': '原生属性,设置最小值',
'en-US': 'Native attribute, which sets the minimum value'
},
demoId: 'native-attributes'
},
{
name: 'minlength',
type: 'Number',
defaultValue: '',
desc: {
'zh-CN': '<p>原生属性,最小输入长度</p>',
'en-US': 'display different button'
'zh-CN': '原生属性,最小输入长度',
'en-US': 'Native attribute, minimum input length'
},
demoId: 'max-min-length'
demoId: 'counter'
},
{
name: 'mobile-tips',
type: 'String',
name: 'tips',
type: 'String | Slot',
defaultValue: '',
desc: {
'zh-CN': '<p>原生属性,设置最小值</p>',
'en-US': 'display different button'
'zh-CN': '提示信息',
'en-US': 'tips under input'
},
demoId: 'type-be-form-tips'
demoId: 'slots'
},
{
name: 'name',
type: 'String',
defaultValue: '',
desc: {
'zh-CN': '<p>原生属性</p>',
'en-US': 'display different button'
'zh-CN': '原生 name 属性',
'en-US': 'native name attribute'
},
demoId: 'props'
demoId: 'native-attributes'
},
{
name: 'placeholde',
name: 'placeholder',
type: 'String',
defaultValue: '',
desc: {
'zh-CN': '<p>输入框占位文本</p>',
'en-US': 'display different button'
'zh-CN': '输入框占位文本',
'en-US': 'placeholder text'
},
demoId: 'prefix-suffix'
demoId: 'basic-usage'
},
{
name: 'prefix-icon',
type: 'Component',
defaultValue: '',
desc: {
'zh-CN': '输入框头部图标',
'en-US': 'Icon at the head'
},
demoId: 'prefix-suffix-icon'
},
{
name: 'readonly',
type: 'Boolean',
defaultValue: 'false',
desc: {
'zh-CN': '<p>原生属性是否只读该属性默认为false</p>',
'en-US': 'display different button'
'zh-CN': '原生属性,是否只读',
'en-US': 'Native attribute, read-only'
},
demoId: 'props'
demoId: 'native-attributes'
},
{
name: 'rows',
type: 'Number',
defaultValue: '2',
desc: {
'zh-CN': '<p>输入框行数,只对 type="textarea"有效该属性默认为2</p>',
'en-US': 'display different button'
'zh-CN': '输入框行数,只对 type="textarea"有效',
'en-US': 'Number of lines in the input box. This parameter is valid only for type="textarea"'
},
demoId: 'cols-rows'
demoId: 'textarea-rows-cols'
},
{
name: 'select-menu',
type: 'Array',
defaultValue: '',
desc: {
'zh-CN': '<p>type为form时设置输入框可下拉选择,设置选择项</p>',
'en-US': 'display different button'
'zh-CN': '下拉选择的选项',
'en-US': 'options of select'
},
demoId: 'type-be-form-select'
demoId: 'type-select'
},
{
name: 'show-password',
type: 'Boolean',
defaultValue: 'false',
desc: {
'zh-CN': '<p>是否显示切换密码图标该属性默认为false</p>',
'en-US': 'display different button'
'zh-CN': '是否显示切换密码图标',
'en-US': 'Whether to display the switchover password icon'
},
demoId: 'show-password'
},
@ -467,8 +432,9 @@ export default {
type: 'Boolean',
defaultValue: 'false',
desc: {
'zh-CN': '<p>是否显示输入字数统计,只在 type = text 或 type = textarea 时有效该属性默认为false</p>',
'en-US': 'display different button'
'zh-CN': '是否显示输入字数统计,只在 type = text 或 type = textarea 时有效该属性默认为false',
'en-US':
'Whether to display the number of input words. This parameter is valid only when type is "text" or type is "textarea"'
},
demoId: 'counter'
},
@ -477,70 +443,71 @@ export default {
type: 'Number',
defaultValue: '',
desc: {
'zh-CN': '<p>原生属性,设置输入字段的合法数字间隔</p>',
'en-US': 'display different button'
'zh-CN': '原生属性,设置输入字段的合法数字间隔',
'en-US': 'Native attribute, which is used to set the valid digit interval of the input field'
},
demoId: 'props-step'
demoId: 'native-attributes'
},
{
name: 'suffix-icon',
type: 'String',
defaultValue: '',
desc: {
'zh-CN': '<p>输入框尾部图标</p>',
'en-US': 'display different button'
'zh-CN': '输入框尾部图标',
'en-US': 'Icon at the right'
},
demoId: 'suffix-icon'
demoId: 'prefix-suffix-icon'
},
{
name: 'textarea-title',
type: 'String',
defaultValue: '标题',
name: 'title',
type: 'String | Slot',
defaultValue: '',
desc: {
'zh-CN': '<p>textarea类型自定义标题,该属性默认为‘标题’</p>',
'en-US': 'display different button'
'zh-CN': '自定义标题',
'en-US': 'custom title'
},
demoId: 'autosize'
demoId: ''
},
{
name: ' type',
name: 'type',
type: 'String',
defaultValue: 'text',
desc: {
'zh-CN': '<p>input 元素的类型,该属性默认为"text"</p>',
'en-US': 'display different button'
'zh-CN': '类型,同原生 input 标签的 type 属性',
'en-US': 'the type of input'
},
demoId: 'autofocus'
demoId: 'type'
},
{
name: 'validate-event',
type: 'Boolean',
defaultValue: 'true',
desc: {
'zh-CN': '<p>输入时是否触发表单的校验该属性默认为true</p>',
'en-US': 'display different button'
'zh-CN': '输入时是否触发表单的校验',
'en-US': ' Whether form validation is triggered when entering data'
},
demoId: 'validate-event'
},
{
name: 'value / v-model',
name: 'v-model / modelValue',
type: 'String',
defaultValue: '',
desc: {
'zh-CN': '<p>绑定值</p>',
'en-US': 'display different button'
'zh-CN': '绑定值',
'en-US': 'input value'
},
demoId: 'autofocus'
demoId: 'basic-usage'
},
{
name: 'vertical',
type: 'Number',
name: 'width',
type: 'Number | String',
defaultValue: '',
desc: {
'zh-CN': '<p>原生属性,设置最小值</p>',
'en-US': 'display different button'
'zh-CN': '宽度,取值为数字或元素 width 属性有效值,如果是数字则以 px 为单位',
'en-US':
'width, accepts a numerical value or a valid value for the width property, and if it is a number, it is measured in pixels.'
},
demoId: 'autofocus'
demoId: ''
}
],
methods: [
@ -549,30 +516,30 @@ export default {
type: '',
defaultValue: '',
desc: {
'zh-CN': '<p>使 input 失去焦点</p>',
'en-US': 'display different button'
'zh-CN': '使 input 失去焦点',
'en-US': 'Make the input lose focus.'
},
demoId: 'blur-focus'
demoId: 'methods'
},
{
name: 'focus',
type: '',
defaultValue: '',
desc: {
'zh-CN': '<p>使 input 获取焦点</p>',
'en-US': 'display different button'
'zh-CN': '使 input 获取焦点',
'en-US': 'Focus the input'
},
demoId: 'blur-focus'
demoId: 'methods'
},
{
name: 'select',
type: '',
defaultValue: '',
desc: {
'zh-CN': '<p>选中 input 中的文字</p>',
'en-US': 'display different button'
'zh-CN': '选中 input 中的文字',
'en-US': 'Select the text in the input'
},
demoId: 'method-select'
demoId: 'methods'
}
],
events: [
@ -581,8 +548,8 @@ export default {
type: '',
defaultValue: '',
desc: {
'zh-CN': '<p>在 Input 值改变时触发</p>',
'en-US': 'Click'
'zh-CN': '在 Input 值改变时触发',
'en-US': 'callback when value has changed'
},
demoId: 'events'
},
@ -591,40 +558,40 @@ export default {
type: '',
defaultValue: '',
desc: {
'zh-CN': '<p>在 在 Input 失去焦点时触发</p>',
'en-US': 'Click'
'zh-CN': '在 Input 失去焦点时触发',
'en-US': 'callback when input lost focus'
},
demoId: 'blur-focus'
demoId: 'events'
},
{
name: 'focus',
type: '',
defaultValue: '',
desc: {
'zh-CN': '<p>在 Input 获得焦点时触发</p>',
'en-US': 'Click'
'zh-CN': '在 Input 获得焦点时触发',
'en-US': 'callback when input gains focus'
},
demoId: 'blur-focus'
demoId: 'events'
},
{
name: 'clear',
type: '',
defaultValue: '',
desc: {
'zh-CN': '<p>在点击由 clearable 属性生成的清空按钮时触发</p>',
'en-US': 'Click'
'zh-CN': '在点击由 clearable 属性生成的清空按钮时触发',
'en-US': 'callback when click clear icon'
},
demoId: 'blur-focus'
demoId: 'events'
},
{
name: 'input',
type: '',
defaultValue: '',
desc: {
'zh-CN': '<p>输入值时触发事件</p>',
'en-US': 'Click'
'zh-CN': '输入值时触发事件',
'en-US': 'callback when user input'
},
demoId: 'input-event'
demoId: 'events'
}
],
slots: [
@ -633,50 +600,52 @@ export default {
type: '',
defaultValue: '',
desc: {
'zh-CN': '<p>输入框后置内容,只对 type="text"有效</p>',
'en-US': 'slots-append-prepend'
'zh-CN': '输入框后置内容,只对 type="text"有效',
'en-US': 'append content for input fields only works with type="text"'
},
demoId: ''
demoId: 'slots'
},
{
name: 'prepend',
type: '',
defaultValue: '',
desc: {
'zh-CN': '<p>输入框前置内容,只对 type="text"有效</p>',
'en-US': 'slots-append-prepend'
'zh-CN': '输入框前置内容,只对 type="text"有效',
'en-US': 'prepend content for input fields only works with type="text"'
},
demoId: ''
demoId: 'slots'
},
{
name: 'prefix',
type: '',
defaultValue: '',
desc: {
'zh-CN': '<p>输入框头部内容,只对 type="text"有效</p>',
'en-US': 'Click'
'zh-CN': '输入框头部内容,只对 type="text"有效',
'en-US': 'prefix content for input fields only works with type="text"'
},
demoId: 'prefix-suffix'
demoId: 'slots'
},
{
name: 'suffix',
type: '',
defaultValue: '',
desc: {
'zh-CN': '<p>输入框尾部内容,只对 type="text"有效</p>',
'en-US': 'Click'
'zh-CN': '输入框尾部内容,只对 type="text"有效',
'en-US': 'suffix content for input fields only works with type="text"'
},
demoId: 'prefix-suffix'
demoId: 'slots'
},
{
name: 'content',
type: '',
defaultValue: '',
name: 'title',
desc: {
'zh-CN': '<p>输入框头部内容插槽,只对 type="textarea"有效</p>',
'en-US': 'Click'
'zh-CN': '标题插槽',
'en-US': 'title slot'
},
demoId: 'slot-content'
demoId: 'slots'
},
{
name: 'tips',
desc: {
'zh-CN': '提示信息插槽',
'en-US': 'tips slot'
},
demoId: 'slots'
}
]
}

View File

@ -0,0 +1,38 @@
<template>
<div class="mobile-mask-demo">
<tiny-button @click="visible = true">点击展示遮罩层</tiny-button>
<p v-if="showMsg">遮罩层click事件已触发</p>
<tiny-mask v-model:visible="visible" @click="handleClick"></tiny-mask>
</div>
</template>
<script>
import { Mask, Button } from '@opentiny/vue'
export default {
components: {
TinyMask: Mask,
TinyButton: Button
},
data() {
return {
visible: false,
showMsg: false
}
},
methods: {
handleClick() {
this.showMsg = true
}
},
}
</script>
<style scoped>
.mobile-mask-demo {
height: 100%;
background: #f4f4f4;
}
</style>

View File

@ -0,0 +1,32 @@
<template>
<div class="mobile-mask-demo">
<tiny-button @click="visible=true">点击显示遮罩层</tiny-button>
<tiny-mask v-model:visible="visible" :cancel-touch="true">
<tiny-button @click="visible=false">点击此处关闭遮罩层</tiny-button>
</tiny-mask>
</div>
</template>
<script>
import { Mask, Button } from '@opentiny/vue'
export default {
components: {
TinyMask: Mask,
TinyButton: Button
},
data() {
return {
visible: false
}
}
}
</script>
<style scoped>
.mobile-mask-demo {
height: 100%;
background: #f4f4f4;
}
</style>

View File

@ -0,0 +1,37 @@
<template>
<div class="mobile-mask-demo">
<tiny-button @click="visible = true">默认插槽示例</tiny-button>
<tiny-mask v-model:visible="visible">
<div class="mask-content">
<p>这是自定义内容</p>
</div>
</tiny-mask>
</div>
</template>
<script>
import { Mask, Button } from '@opentiny/vue'
export default {
components: {
TinyMask: Mask,
TinyButton: Button
},
data() {
return {
visible: false
}
}
}
</script>
<style scoped>
.mask-content {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: 10px 20px;
background: #eee;
}
</style>

View File

@ -0,0 +1,11 @@
---
title: Mask 列表
---
# Mask 遮罩层
<div>
遮罩层通常用于覆盖在页面上,以阻止用户对页面或元素的操作,同时可以显示一些提示信息或加载状态等。
</div>

View File

@ -0,0 +1,11 @@
---
title: Mask
---
# Mask
<div>
A mask layer is typically used to cover a page, preventing users from interacting with the page or elements, while displaying some informational or loading state messages.
</div>

View File

@ -0,0 +1,114 @@
export default {
column: '2',
owner: '',
demos: [
{
demoId: 'base',
name: {
'zh-CN': '基本使用',
'en-US': 'left right arrow'
},
desc: {
'zh-CN': '<p>通过 <code>v-model:visible</code> 属性设置显示与隐藏遮罩层;<code>click</code> 监听点击事件。</p>',
'en-US': '<p>double-line</p>'
},
codeFiles: ['basic-usage.vue']
},
{
demoId: 'cancel-touch',
name: {
'zh-CN': '点击遮罩层不隐藏',
'en-US': 'No hide after clicking'
},
desc: {
'zh-CN': '<p>通过 <code>cancel-touch</code> 属性设置点击遮罩层后组件不隐藏</p>',
'en-US':
'<p>"By setting the <code>cancel-touch</code> attribute, the component will not be hidden when clicking on the mask layer.</p>'
},
codeFiles: ['click-no-hide.vue']
},
{
demoId: 'z-index',
name: {
'zh-CN': '层叠数值',
'en-US': 'z-index'
},
desc: {
'zh-CN': '<p>通过 <code>z-index</code> 属性设置层叠数值。</p>',
'en-US': '<p>"Use the <code>z-index</code> attribute to set z-index of CSS property.</p>'
},
codeFiles: ['z-index.vue']
},
{
demoId: 'slot-default',
name: {
'zh-CN': '默认插槽',
'en-US': 'Default slot'
},
desc: {
'zh-CN': '<p>通过 <code>default</code> 默认插槽自定义嵌入内容。</p>',
'en-US':
'<p>"By setting the <code>cancel-touch</code> attribute, the component will not be hidden when clicking on the mask layer.</p>'
},
codeFiles: ['slot-default.vue']
}
],
apis: [
{
name: 'Mask',
type: 'component',
properties: [
{
name: 'cancelTouch',
type: 'boolean',
defaultValue: 'false',
desc: {
'zh-CN': '是否禁用touch事件设为 <code>true</code> 后点击遮罩层不会关闭',
'en-US': "whether to disable touch events, and mask wouldn't close when it was set <code>true</code>"
},
demoId: 'cancel-touch'
},
{
name: 'visible',
type: 'boolean',
defaultValue: 'false',
desc: {
'zh-CN': '是否展示遮罩层',
'en-US': 'whether to show mask layer'
},
demoId: 'base'
},
{
name: 'z-index',
type: 'number',
defaultValue: '99',
desc: {
'zh-CN': '层叠数值',
'en-US': 'z-index property'
},
demoId: 'z-index'
}
],
events: [
{
name: 'click',
desc: {
'zh-CN': '点击遮罩层触发',
'en-US': 'Click'
},
demoId: 'basic-usage'
}
],
slots: [
{
name: 'default',
desc: {
'zh-CN': '默认插槽',
'en-US': 'Default slot'
},
demoId: 'slot-default'
}
]
}
]
}

View File

@ -0,0 +1,30 @@
<template>
<div class="mobile-mask-demo">
<tiny-button @click="visible = true">点击展示遮罩层</tiny-button>
<tiny-mask v-model:visible="visible" :z-index="zIndex"></tiny-mask>
</div>
</template>
<script>
import { Mask, Button } from '@opentiny/vue'
export default {
components: {
TinyMask: Mask,
TinyButton: Button
},
data() {
return {
visible: false,
zIndex: 9999
}
},
}
</script>
<style scoped>
.mobile-mask-demo {
height: 100%;
background: #f4f4f4;
}
</style>

View File

@ -98,7 +98,8 @@ export const cmpMenus = [
{ name: 'Loading', nameCn: '加载', key: 'loading' },
{ name: 'Modal', nameCn: '模态框', key: 'modal' },
{ name: 'Popover', nameCn: '气泡', key: 'popover' },
{ name: 'Toast', nameCn: '轻提示', key: 'toast' }
{ name: 'Toast', nameCn: '轻提示', key: 'toast' },
{ name: 'Mask', nameCn: '遮罩层', key: 'mask' }
]
},
{

View File

@ -0,0 +1,34 @@
const fs = require('fs');
const basePath = '.';
const readFile = function (path) {
let componentCount = 0;
let apiCount = 0;
const readDir = fs.readdirSync(path);
readDir.forEach(i => {
const curDir = `${path}/${i}`;
const stat = fs.statSync(curDir);
if (stat.isFile() && i.endsWith('.json')) {
componentCount += 1;
const data = fs.readFileSync(curDir, 'utf-8');
let dataJson = null;
try {
dataJson = JSON.parse(data);
} catch (err) {
console.log('err:', err);
}
if (dataJson !== null) {
apiCount += (dataJson.attrs?.length || 0) + (dataJson.slots?.length || 0) + (dataJson.events?.length || 0) + (dataJson.methods?.length || 0);
}
}
});
console.log('componentCount:', componentCount);
console.log('apiCount:', apiCount);
}
readFile(basePath);

View File

@ -31,3 +31,10 @@ export default {
}
}
</script>
<style scoped>
:deep(.tiny-drawer .tiny-drawer__main.is-right) {
height: calc(100% - 50px);
margin-top: 50px;
}
</style>

353
gulp/buildLowcodeBundle.mjs Normal file
View File

@ -0,0 +1,353 @@
import gulp from 'gulp'
import minimist from 'minimist'
import shell from 'shelljs'
import path from 'path'
import { generateKey } from 'crypto'
const build = gulp.series(init, read, write, clean)
build.description = '将本地文档的组件api, 转换为低代码需要的bundle.json 格式'
build.flags = {
'--apiPath': '设置api文档路径默认为 examples/sites/demos/pc',
'--tinyVer': '设置生成中tinyVer的版本号默认为 3.11.0'
}
export default build
const rootPath = process.cwd()
let apiPath = 'examples/sites/demos/pc'
let tinyVer = '3.11.0'
let guid = 1
let menus = []
const ignoreKeys = ['color', 'font', 'icon']
const mixinKeys = {
'form': [{ key: 'form-item', nameCn: '表单项', desc: '表单中的一行表单域对象' }],
'layout': [
{ key: 'row', nameCn: '行元素', desc: '行元素' },
{ key: 'col', nameCn: '列元素', desc: '列元素' }
],
'breadcrumb': [{ key: 'breadcrumb-item', nameCn: '面包屑项', desc: '面包屑的层级对象' }],
'timeline': [{ key: 'timeline-item', nameCn: '时间线数据项', desc: '时间线数据项' }],
'dropdown': [
{ key: 'dropdown-menu', nameCn: '下拉菜单', desc: '下拉菜单' },
{ key: 'dropdown-item', nameCn: '下拉菜单项', desc: '下拉菜单项' }
],
'carousel': [{ key: 'carousel-item', nameCn: '走马灯数据项', desc: '走马灯数据项' }],
'checkbox': [
{ key: 'checkbox-group', nameCn: '复选框组', desc: '复选框组' },
{ key: 'checkbox-button', nameCn: '复选框按钮', desc: '复选框按钮' }
],
'radio': [
{ key: 'radio-group', nameCn: '单选框组', desc: '单选框组' },
{ key: 'radio-button', nameCn: '单选框按钮', desc: '单选框按钮' }
],
'grid': [
{ key: 'grid-column', nameCn: '表格列对象', desc: '表格列对象' },
{ key: 'grid-toolbar', nameCn: '表格工具栏', desc: '表格工具栏' }
]
}
const result = {
'data': {
'framework': 'Vue',
'materials': {
'components': [],
'snippets': [],
'blocks': []
}
}
}
// 1. 初始化
function init(cb) {
const argv = minimist(process.argv.slice(2))
if (argv.apiPath) {
apiPath = argv.apiPath
}
if (argv.tinyVer) {
tinyVer = argv.tinyVer
}
// 读菜单
shell.cp(path.join(apiPath, '/menus.js'), 'gulp/menus.mjs')
shell.sed('-i', 'import.meta.env.VITE_BUILD_TARGET', 'false', 'gulp/menus.mjs')
import('./menus.mjs').then((res) => {
menus = res.cmpMenus
cb()
})
}
// 2. 遍历菜单,处理每一个组件
function read(cb) {
menus.forEach((group) => {
const snippetItem = {
'group': group.label,
'children': []
}
group.children.forEach((component) => {
if (ignoreKeys.includes(component.key)) {
return
}
if (component.key.startsWith('grid-') || component.key.startsWith('chart-')) {
return
}
const componentInfo = _readOneComp(component)
const componentItem = genComp(componentInfo)
const snipItem = genSnip(componentInfo)
result.data.materials.components.push(componentItem)
snippetItem.children.push(snipItem)
// 特殊的混合组件判断, 比如遍历到form时要插入 form-item的定义
if (mixinKeys[component.key]) {
mixinKeys[component.key].forEach((mixin) => {
const componentInfo = _readOneComp(component, mixin)
const componentItem = genComp(componentInfo)
const snipItem = genSnip(componentInfo)
result.data.materials.components.push(componentItem)
snippetItem.children.push(snipItem)
})
}
})
result.data.materials.snippets.push(snippetItem)
})
cb()
}
function _readOneComp(component, mixin = '') {
if (!mixin) {
shell.echo('---正在读取组件', component.key)
const key = component.key
const camelizeKey = camelize(key)
const cmpName = component.nameCn
const desc = readMdDesc(key)
const jsStr = shell.cat(`${apiPath}/app/${key}/webdoc/${key}.js`).replace('export default', '(') + ')'
const api = eval(jsStr).apis.filter((item) => item.name === key)[0]
const props = api?.props || api?.properties || []
const events = api?.events || []
const slots = api?.slots || []
guid++
const componentInfo = { id: guid, version: tinyVer, key, camelizeKey, cmpName, desc, props, events, slots }
return componentInfo
} else {
shell.echo('---正在读取混入的组件', component.key, mixin.key)
const key = mixin.key
const camelizeKey = camelize(key)
const cmpName = mixin.nameCn
const desc = mixin.desc
const jsStr =
shell.cat(`${apiPath}/app/${component.key}/webdoc/${component.key}.js`).replace('export default', '(') + ')'
const api = eval(jsStr).apis.filter((item) => item.name === mixin.key)[0]
const props = api?.props || api?.properties || []
const events = api?.events || []
const slots = api?.slots || []
guid++
const componentInfo = { id: guid, version: tinyVer, key, camelizeKey, cmpName, desc, props, events, slots }
return componentInfo
}
}
// 3. 将结果写bundle.json
function write(cb) {
shell.ShellString(JSON.stringify(result, null, ' ')).to('gulp/bundle.json')
cb()
}
// 4. 清除
function clean(cb) {
shell.rm('gulp/menus.mjs')
cb()
}
// 以下辅助方法
// 转换button-group ==> ButtonGroup
const camelize = (str) => {
return str
.replace(/-(\w)/g, (_, c) => (c ? c.toUpperCase() : ''))
.replace(/^(\w)/g, (_, c) => (c ? c.toUpperCase() : ''))
}
// 从标签中,提取文字。 <div>常用的操作按钮。</div> ==> 常用的操作按钮。
const readMdDesc = (key) => {
const mdStr = shell.cat(`${apiPath}/app/${key}/webdoc/${key}.cn.md`)
const matched = mdStr.match(/<div>([\w|\s|\u4e00-\u9fa5]*)<\/div>/i)
return matched ? matched[1] || '' : ''
}
const genComp = ({ id, version, key, camelizeKey, cmpName, desc, props, events, slots }) => {
const item = {
'id': id,
'version': version,
'name': {
'zh_CN': cmpName
},
'component': 'Tiny' + camelizeKey,
'icon': '',
'description': desc,
'doc_url': '',
'screenshot': '',
'tags': '',
'keywords': '',
'dev_mode': 'proCode',
'npm': {
'package': '@opentiny/vue',
'exportName': camelizeKey,
'version': version,
'destructuring': true
},
'group': 'component',
'configure': {
'loop': true,
'condition': true,
'styles': true,
'isContainer': false,
'isModal': false,
'nestingRule': {
'childWhitelist': '',
'parentWhitelist': '',
'descendantBlacklist': '',
'ancestorWhitelist': ''
},
'isNullNode': false,
'isLayout': false,
'rootSelector': '',
'shortcuts': {
'properties': []
},
'contextMenu': {
'actions': [],
'disable': []
},
'framework': 'Vue'
},
'schema': {
'properties': [
{
'label': {
'zh_CN': '基础信息'
},
'description': {
'zh_CN': '基础信息'
},
'collapse': {
'number': 6,
'text': {
'zh_CN': '显示更多'
}
},
'content': props.map((prop) => genProp(prop))
}
],
'events': {
...events.map((event) => genEvent(event)).reduce((pre, curr) => ({ ...pre, ...curr }), {})
},
'slots': {
...slots.map((slot) => genSlot(slot)).reduce((pre, curr) => ({ ...pre, ...curr }), {})
}
}
}
return item
}
const genProp = ({ name, type, defaultValue, desc }) => {
const typeMap = {
string: {
component: 'MetaInput',
props: {}
},
boolean: {
component: 'MetaSwitch',
props: {}
},
number: {
component: 'MetaNumberic',
props: {}
},
object: {
component: 'MetaCodeEditor',
props: {
language: 'json'
}
},
array: {
component: 'MetaCodeEditor',
props: {
language: 'json'
}
},
function: {
component: 'MetaCodeEditor',
props: {
language: 'javascript'
}
}
}
const normalizeType = type.trim().toLowerCase()
return {
'property': name,
'type': type,
'defaultValue': defaultValue == '--' ? '' : defaultValue,
'label': {
'text': {
'zh_CN': desc['zh-CN']
}
},
'cols': 12,
'rules': [],
'hidden': false,
'required': true,
'readOnly': true,
'disabled': true,
'widget': typeMap[normalizeType]
? typeMap[normalizeType] //
: { 'component': '', 'props': {} },
'description': {
'zh_CN': desc['zh-CN']
}
}
}
const genEvent = ({ name, type, defaultValue, desc }) => {
return {
['on' + camelize(name)]: {
'label': {
'zh_CN': desc['zh-CN']
},
'description': {
'zh_CN': desc['zh-CN']
},
'type': 'event',
'functionInfo': {
'params': [],
'returns': {}
},
'defaultValue': ''
}
}
}
const genSlot = ({ name, type, defaultValue, desc }) => {
return {
[name]: {
'label': {
'zh_CN': desc['zh-CN']
},
'description': {
'zh_CN': desc['zh-CN']
}
}
}
}
const genSnip = ({ id, version, key, camelizeKey, cmpName, desc, props, events, slots }) => {
return {
'name': {
'zh_CN': cmpName
},
'icon': key,
'screenshot': '',
'snippetName': 'Tiny' + camelizeKey,
'schema': {}
}
}

View File

@ -3,5 +3,6 @@ import buildRenderless from './gulp/buildRenderless.mjs'
import buildTheme from './gulp/buildTheme.mjs'
import themeJson from './gulp/themeJson.mjs'
import themeConcat from './gulp/themeConcat.mjs'
import lowcode from './gulp/buildLowcodeBundle.mjs'
export { themeJson, themeConcat, buildVue, buildRenderless, buildTheme }
export { themeJson, themeConcat, buildVue, buildRenderless, buildTheme, lowcode }

View File

@ -1557,6 +1557,14 @@
"type": "template",
"exclude": false
},
"Mask": {
"path": "vue/src/mask/index.ts",
"type": "component",
"exclude": false,
"mode": [
"mobile"
]
},
"Menu": {
"path": "vue/src/menu/index.ts",
"type": "component",

View File

@ -9,7 +9,50 @@
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
import type { IAlertRenderlessParams } from '@/types'
import type { CSSProperties } from 'vue'
import type { IAlertRenderlessParams, ITinyVm } from '@/types'
export const ALERT_TIMEOUT = 2000
export const watchAutoHide =
({ api, props }: Pick<IAlertRenderlessParams, 'api' | 'props'>) =>
(newVal: boolean) => {
if (props.autoHide && newVal) {
const timer = setTimeout(() => {
api.handleClose()
clearTimeout(timer)
}, ALERT_TIMEOUT)
}
}
export const computedClass =
({ props, mode }) =>
(): string[] => {
const { type, size, center } = props
if (mode === 'mobile') {
const alertClass = ['tiny-mobile-alert', 'tiny-mobile-alert--' + type, 'tiny-mobile-alert--' + size]
if (center) {
alertClass.push('is-center')
}
return alertClass
}
return []
}
export const computedStyle =
({ props, mode }) =>
(): CSSProperties | null => {
if (mode === 'mobile') {
const style = {
top: isNaN(props.offset) ? props.offset : `${props.offset}px`
}
return style
}
return null
}
export const handleClose =
({ emit, state }: Pick<IAlertRenderlessParams, 'emit' | 'state'>) =>
@ -52,3 +95,23 @@ export const handleHeaderClick =
}
}
}
const getEl = (node: ITinyVm): HTMLElement => {
return node.$el || node
}
export const handlerTargetNode =
({ props, parent, vm, nextTick }) =>
() => {
const { target } = props
const { $parent } = parent
nextTick(() => {
const alertParentNode = $parent?.$refs[target]
if (!target || !alertParentNode) {
return
}
const targetNode = Array.isArray(alertParentNode) ? alertParentNode[0] : alertParentNode
getEl(targetNode).insertBefore(vm.$el, getEl(targetNode).firstChild)
})
}

View File

@ -10,40 +10,63 @@
*
*/
import type {
IAlertApi,
IAlertProps,
IAlertState,
ISharedRenderlessParamHooks,
IAlertRenderlessParamUtils
} from '@/types'
import { handleClose, computedGetIcon, computedGetTitle, handleHeaderClick } from './index'
import type{ IAlertApi, IAlertProps, IAlertState, ISharedRenderlessParamHooks, IAlertRenderlessParamUtils } from '@/types'
import {
computedGetIcon,
computedGetTitle,
computedStyle,
computedClass,
handleClose,
handleHeaderClick,
watchAutoHide,
handlerTargetNode
} from './index'
export const api = ['handleClose', 'state', 'handleHeaderClick']
export const renderless = (
props: IAlertProps,
{ computed, reactive }: ISharedRenderlessParamHooks,
{ t, emit, constants, vm, designConfig }: IAlertRenderlessParamUtils
): IAlertApi => {
const state: IAlertState = reactive({
const initState = ({ api, computed, constants, reactive }): IAlertState => {
return reactive({
show: true,
getIcon: computed(() => api.computedGetIcon()),
getTitle: computed(() => api.computedGetTitle()),
contentVisible: false,
contentDescribeHeight: 0,
contentDefaultHeight: 0,
contentMaxHeight: constants.CONTENT_MAXHEUGHT,
scrollStatus: false
scrollStatus: false,
getIcon: computed(() => api.computedGetIcon()),
getTitle: computed(() => api.computedGetTitle()),
alertClass: computed(() => api.computedClass()),
alertStyle: computed(() => api.computedStyle())
})
}
const api: IAlertApi = {
const initApi = ({ api, state, constants, props, designConfig, t, emit, vm, parent, nextTick, mode }): void => {
Object.assign(api, {
state,
computedGetIcon: computedGetIcon({ constants, props, designConfig }),
computedGetTitle: computedGetTitle({ constants, props, t }),
computedClass: computedClass({ props, mode }),
computedStyle: computedStyle({ props, mode }),
handleClose: handleClose({ emit, state }),
handleHeaderClick: handleHeaderClick({ state, props, vm })
}
handleHeaderClick: handleHeaderClick({ state, props, vm }),
watchAutoHide: watchAutoHide({ api, props }),
handlerTargetNode: handlerTargetNode({ props, parent, vm, nextTick })
})
}
const initWatcher = ({ watch, props, api }) => {
watch(() => props.autoHide, api.watchAutoHide, { immediate: true })
watch(() => props.target, api.handlerTargetNode, { immediate: true })
}
export const renderless = (
props: IAlertProps,
{ computed, reactive, watch }: ISharedRenderlessParamHooks,
{ t, emit, constants, vm, designConfig, parent, nextTick, mode }: IAlertRenderlessParamUtils
): IAlertApi => {
const api = {} as IAlertApi
const state: IAlertState = initState({ api, computed, constants, reactive })
initApi({ api, state, constants, props, designConfig, t, emit, vm, parent, nextTick, mode })
initWatcher({ watch, props, api })
return api
}

View File

@ -38,5 +38,7 @@ export const renderless = (props, { computed, reactive, watch, provide }, { disp
provide('vertical', props.vertical)
provide('iconPosition', props.iconPosition)
return api
}

View File

@ -46,6 +46,7 @@ const initState = ({ reactive, computed, parent, api, inject, props }) => {
const state: ICheckboxState = reactive({
size: props.size || inject('size', null),
vertical: inject('vertical', null),
iconPosition: props.iconPosition || inject('iconPosition', 'center'),
focus: false,
selfModel: false,
showLabel: false,

View File

@ -62,6 +62,14 @@ export const showBox = (state: IInputState) => (): void => {
state.boxVisibility = true
}
export const inputStyle =
({ props }) =>
() => {
return {
textAlign: props.textAlign
}
}
export const calculateNodeStyling =
() =>
(
@ -387,7 +395,7 @@ export const watchFormSelect =
const filterData = props.selectMenu.length && props.selectMenu.filter((item) => item.id === value).shift()
state.checkedLable = filterData ? filterData.label : ''
state.checkedLabel = filterData ? filterData.label : ''
}
}

View File

@ -47,7 +47,8 @@ import {
handleEnterDisplayOnlyContent,
hiddenPassword,
dispatchDisplayedValue,
getDisplayedValue
getDisplayedValue,
inputStyle
} from './index'
import useStorageBox from '../tall-storage/vue-storage-box'
@ -81,7 +82,8 @@ export const api = [
'isMemoryStorage',
'hasSelection',
'handleEnterDisplayOnlyContent',
'hiddenPassword'
'hiddenPassword',
'inputStyle'
]
const initState = ({
@ -101,7 +103,7 @@ const initState = ({
passwordVisible: false,
boxVisibility: false,
textareaCalcStyle: {},
checkedLable: '',
checkedLabel: '',
sheetvalue: props.modelValue,
inputSize: computed(() => props.size || state.formItemSize),
showClear: computed(
@ -123,9 +125,11 @@ const initState = ({
props.disabled || (parent.tinyForm || {}).disabled || state.isDisplayOnly || (parent.tinyForm || {}).displayOnly
),
validateState: computed(() => (parent.formItem ? parent.formItem.validateState : '')),
inputStyle: computed(() => api.inputStyle()),
textareaStyle: computed(() => ({
...state.textareaCalcStyle,
resize: props.resize
resize: props.resize,
textAlign: props.textAlign
})),
needStatusIcon: computed(() => (parent.tinyForm ? parent.tinyForm.statusIcon : false)),
showPwdVisible: computed(
@ -186,7 +190,8 @@ const initApi = ({
handleCompositionStart: handleCompositionStart(state),
handleCompositionUpdate: handleCompositionUpdate(state),
dispatchDisplayedValue: dispatchDisplayedValue({ state, props, dispatch, api }),
getDisplayedValue: getDisplayedValue({ state, props })
getDisplayedValue: getDisplayedValue({ state, props }),
inputStyle: inputStyle({ props })
})
}

View File

@ -0,0 +1,24 @@
/**
* Copyright (c) 2022 - present TinyVue Authors.
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
export const handleTouch =
({ props, emit }) =>
(event: TouchEvent) => {
if (props.cancelTouch) {
event.preventDefault()
event.stopPropagation()
} else {
emit('update:visible', false)
}
emit('click', props.visible)
}

View File

@ -0,0 +1,29 @@
/**
* Copyright (c) 2022 - present TinyVue Authors.
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
import { handleTouch } from './index'
export const api = ['state', 'handleTouch']
export const renderless = (props, { reactive, computed }, { emit }) => {
const api = {}
const state = reactive({
calcStyle: computed(() => ({ zIndex: props.zIndex }))
})
Object.assign(api, {
state,
handleTouch: handleTouch({ props, emit })
})
return api
}

View File

@ -1,5 +1,5 @@
import type { ExtractPropTypes } from 'vue'
import type { alertProps, $constants } from '@/alert/src'
import type { ExtractPropTypes, CSSProperties } from 'vue'
import { alertProps, $constants } from '@/alert/src'
import type { ISharedRenderlessFunctionParams, ISharedRenderlessParamUtils } from './shared.type'
export interface IAlertState {
@ -18,6 +18,7 @@ export type IAlertProps = ExtractPropTypes<typeof alertProps>
export type IAlertConstants = typeof $constants
export type IAlertRenderlessParams = ISharedRenderlessFunctionParams<IAlertConstants> & {
api: IAlertApi
state: IAlertState
props: IAlertProps
}
@ -28,6 +29,8 @@ export interface IAlertApi {
computedGetTitle: () => string
handleClose: () => void
handleHeaderClick: () => void
watchAutoHide: (value: boolean) => void
computedStyle: () => CSSProperties
}
export type IAlertRenderlessParamUtils = ISharedRenderlessParamUtils<IAlertConstants>

View File

@ -15,7 +15,8 @@ import type {
resizeTextarea,
updateIconOffset,
hiddenPassword,
dispatchDisplayedValue
dispatchDisplayedValue,
inputStyle
} from '../src/input'
export interface IInputState {
@ -26,7 +27,8 @@ export interface IInputState {
passwordVisible: boolean
boxVisibility: boolean
textareaCalcStyle: object
checkedLable: string
checkedLabel: string
width: string
sheetvalue: string | number | undefined
inputSize: ComputedRef<string>
showClear: ComputedRef<boolean>
@ -71,6 +73,7 @@ export interface IInputApi extends Pick<IInputRenderlessParamUtils, 'dispatch'>
calcIconOffset: ReturnType<typeof calcIconOffset>
focus: ReturnType<typeof focus>
getDisplayedValue: ReturnType<typeof getDisplayedValue>
inputStyle: ReturnType<typeof inputStyle>
}
export type IInputRenderlessParams = ISharedRenderlessFunctionParams<IInputConstants> & {

View File

@ -12,6 +12,7 @@
@import '../mixins/alert.less';
@import '../custom.less';
@import '../base/index.less';
@import './vars.less';
@alert-prefix-cls: ~'@{css-prefix}mobile-alert';
@ -19,16 +20,20 @@
.@{alert-prefix-cls} {
clear: both;
position: relative;
font-size: 0;
.@{alert-prefix-cls}__content {
color: var(--ti-mobile-alert-content-text-color);
padding-left: 8px;
}
&--normal {
height: var(--ti-mobile-alert-nomal-height, 30px);
line-height: var(--ti-mobile-alert-nomal-height, 30px);
padding: 0px 16px;
height: var(--ti-mobile-alert-height, 36px);
line-height: 1.5;
padding: var(--ti-mobile-alert-padding-top) var(--ti-mobile-alert-padding-right) var(--ti-mobile-alert-padding-bottom) var(--ti-mobile-alert-padding-left);
.@{alert-prefix-cls}__content {
padding-left: 8px;
font-size: var(--ti-mobile-alert-content-font-size, 12px);
color: var(--ti-mobile-alert-content-color, #999);
display: inline-block;
vertical-align: middle;
@ -39,50 +44,18 @@
}
&&--large {
padding: 10px;
border-radius: var(--ti-mobile-alert-large-border-radius, 4px);
background: var(--ti-mobile-alert-large-bgcolor, #039be5);
&::before {
content: '';
width: 8px;
height: 8px;
border-radius: 50%;
background: var(--ti-mobile-alert-large-bgcolor, #039be5);
display: block;
position: absolute;
top: -24px;
left: 24px;
}
&::after {
content: '';
width: 3px;
height: 24px;
background: var(--ti-mobile-alert-large-bgcolor, #039be5);
display: block;
position: absolute;
top: -24px;
left: 24px;
transform: translateX(2px);
}
padding: var(--ti-mobile-alert-large-padding-vertical) var(--ti-mobile-alert-padding-right) var(--ti-mobile-alert-large-padding-vertical) var(--ti-mobile-alert-padding-left);
.@{alert-prefix-cls}__content {
font-size: 15px;
color: var(--ti-mobile-alert-large-color, #fff);
padding-left: 8px;
display: inline-block;
vertical-align: middle;
&.is-hideicon {
&.is-hideicoalert-variantn {
padding: 0;
}
}
.@{alert-prefix-cls}__icon {
fill: var(--ti-mobile-alert-large-color, #fff);
}
.is-custom {
font-size: 15px;
color: #fff;
@ -91,33 +64,33 @@
&--success {
.alert-variant(
var(--ti-mobile-alert-success-icon-color, #52c41a) ;
var(--ti-mobile-alert-success-link-color, #78d53a) ;
var(--ti-mobile-alert-success-bg-color, #f6ffed)
var(--ti-mobile-alert-success-icon-color) ;
var(--ti-mobile-alert-success-link-color) ;
var(--ti-mobile-alert-success-bg-color)
);
}
&--info {
.alert-variant(
var(--ti-mobile-alert-info-icon-color, #1890ff) ;
var(--ti-mobile-alert-info-link-color, #5ec2ff) ;
var(--ti-mobile-alert-info-bg-color, #e6f7ff)
var(--ti-mobile-alert-info-icon-color) ;
var(--ti-mobile-alert-info-link-color) ;
var(--ti-mobile-alert-info-bg-color)
);
}
&--warning {
.alert-variant(
var(--ti-mobile-alert-warning-icon-color, #faad14) ;
var(--ti-mobile-alert-warning-link-color, #ffc833) ;
var(--ti-mobile-alert-warning-bg-color, #fef6e5)
var(--ti-mobile-alert-warning-icon-color) ;
var(--ti-mobile-alert-warning-link-color) ;
var(--ti-mobile-alert-warning-bg-color)
);
}
&--error {
.alert-variant(
var(--ti-mobile-alert-error-icon-color, #f5222d) ;
var(--ti-mobile-alert-error-link-color, #ff4642) ;
var(--ti-mobile-alert-error-bg-color, #fff1f0)
var(--ti-mobile-alert-error-icon-color) ;
var(--ti-mobile-alert-error-link-color) ;
var(--ti-mobile-alert-error-bg-color)
);
}

View File

@ -1,26 +1,48 @@
:root {
--ti-mobile-alert-warning-icon-color: var(--ti-mobile-base-color-warning-normal, #faad14);
--ti-mobile-alert-warning-link-color: #ffc833;
--ti-mobile-alert-warning-bg-color: #fef6e5;
// 警告类型提示图标色
--ti-mobile-alert-warning-icon-color: var(--ti-mobile-color-warning, #ff8800);
// 警告类型提示链接字体色
--ti-mobile-alert-warning-link-color: var(--ti-mobile-color-text-link, #1476ff);
// 警告类型提示背景色
--ti-mobile-alert-warning-bg-color: var(--ti-mobile-color-warning-subtle, #ffebd1);
--ti-mobile-alert-error-icon-color: var(--ti-mobile-base-color-danger-normal, #f5222d);
--ti-mobile-alert-error-link-color: #ff4642;
--ti-mobile-alert-error-bg-color: #fff1f0;
// 异常类型提示图标色
--ti-mobile-alert-error-icon-color: var(--ti-mobile-color-error, #f23030);
// 异常类型提示链接字体色
--ti-mobile-alert-error-link-color: var(--ti-mobile-color-text-link, #1476ff);
// 异常类型提示背景色
--ti-mobile-alert-error-bg-color: var(--ti-mobile-color-error-subtle, #fce3e1);
--ti-mobile-alert-success-icon-color: var(--ti-mobile-base-color-success-normal, #52c41a);
--ti-mobile-alert-success-link-color: #78d53a;
--ti-mobile-alert-success-bg-color: #f6ffed;
// 成功类型提示图标色
--ti-mobile-alert-success-icon-color: var(--ti-mobile-color-success, #5cb300);
// 成功类型提示链接字体色
--ti-mobile-alert-success-link-color: var(--ti-mobile-color-text-link, #1476ff);
// 成功类型提示背景色
--ti-mobile-alert-success-bg-color: var(--ti-mobile-color-success-subtle, #e6f2d5);
--ti-mobile-alert-info-icon-color: var(--ti-mobile-base-color-primary-normal, #1890ff);
--ti-mobile-alert-info-link-color: #5ec2ff;
--ti-mobile-alert-info-bg-color: var(--ti-mobile-base-color-hover-background, #e6f7ff);
// 基础类型提示图标色
--ti-mobile-alert-info-icon-color: var(--ti-mobile-color-brand-2, #1476ff);
// 基础类型提示链接字体色
--ti-mobile-alert-info-link-color: var(--ti-mobile-color-text-link, #1476ff);
// 基础类型提示背景色
--ti-mobile-alert-info-bg-color: var(--ti-mobile-color-info-subtle, #deecff);
--ti-mobile-alert-nomal-height: var(--ti-mobile-base-size-height-minor, 30px);
--ti-mobile-alert-icon-size: 16px;
--ti-mobile-alert-content-font-size: var(--ti-mobile-base-font-size-base, 12px);
--ti-mobile-alert-content-color: var(--ti-mobile-base-color-placeholder, #999);
--ti-mobile-alert-large-color: var(--ti-mobile-base-color-light, #fff);
--ti-mobile-alert-large-bgcolor: #039be5;
--ti-mobile-alert-large-border-radius: 4px;
// 默认高度
--ti-mobile-alert-height: var(--ti-mobile-color-info-subtle, 36px);
// 默认左内边距
--ti-mobile-alert-padding-left: var(--ti-mobile-space-6x, 24px);
// 默认右内边距
--ti-mobile-alert-padding-right: var(--ti-mobile-space-6x, 24px);
// 默认上内边距
--ti-mobile-alert-padding-top: 9px;
// 默认下内边距
--ti-mobile-alert-padding-bottom: 9px;
// 图标大小
--ti-mobile-alert-icon-size: var(--ti-mobile-font-size-l, 16px);
// 字号
--ti-mobile-alert-content-font-size: var(--ti-mobile-font-size-s, 12px);
// 字体色
--ti-mobile-alert-content-text-color: var(--ti-mobile-color-text-primary, #191919);
// large提示垂直内边距
--ti-mobile-alert-large-padding-vertical: 10px;
}

View File

@ -10,6 +10,7 @@
*
*/
@import '../base/basic-var.less';
@import '../mixins/common.less';
@import '../mixins/checkbox.less';
@import '../custom.less';
@ -21,7 +22,7 @@
position: relative;
display: inline-block;
white-space: nowrap;
margin-right: var(--ti-mobile-checkbox-margin-right, 30px);
margin-right: var(--ti-mobile-checkbox-margin-right);
cursor: pointer;
.user-select(none);
@ -36,16 +37,16 @@
vertical-align: middle;
outline: 0;
cursor: pointer;
width: var(--ti-mobile-checkbox-size, 20px);
height: var(--ti-mobile-checkbox-size, 20px);
line-height: var(--ti-mobile-checkbox-size, 20px);
width: var(--ti-mobile-checkbox-width);
height: var(--ti-mobile-checkbox-height);
line-height: var(--ti-mobile-checkbox-line-height);
}
&__inner {
display: inline-block;
position: relative;
background-color: var(--ti-mobile-checkbox-bg-color, #ffffff);
border: 1px solid var(--ti-mobile-checkbox-border-color, #dbdbdb);
background-color: var(--ti-mobile-checkbox-bg-color);
border: 1.5px solid var(--ti-mobile-checkbox-border-color);
border-radius: var(--ti-mobile-checkbox-border-radius, 3px);
box-sizing: border-box;
width: 100%;
@ -56,7 +57,7 @@
background-color 0.25s cubic-bezier(0.71, -0.46, 0.29, 1.46);
&:hover {
border-color: var(--ti-mobile-checkbox-checked-border-color, #4a79fe);
border-color: var(--ti-mobile-checkbox-checked-border-color);
}
&::after {
@ -64,11 +65,11 @@
content: '';
border-width: 2px;
border-style: solid;
border-color: var(--ti-mobile-checkbox-selected-border-color, #ffffff);
border-color: var(--ti-mobile-checkbox-selected-border-color);
border-left: 0;
border-top: 0;
height: 8px;
width: 5px;
height: 11px;
width: 7px;
position: absolute;
left: 50%;
top: 42%;
@ -91,19 +92,21 @@
&__label {
display: inline-block;
padding-left: 16px;
padding-left: var(--ti-mobile-checkbox-label-padding-left);
line-height: 24px;
color: var(--ti-mobile-checkbox-color, #595959);
color: var(--ti-mobile-checkbox-text-color);
font-size: var(--ti-mobile-checkbox-font-size, 16px);
vertical-align: middle;
word-break: break-all;
white-space: pre-wrap;
}
&.is-checked &__inner {
background-color: var(--ti-mobile-checkbox-checked-bg-color, #4a79fe);
background-color: var(--ti-mobile-checkbox-checked-bg-color);
}
&.is-checked &__inner::after {
border-color: var(--ti-mobile-checkbox-selected-border-color, #ffffff);
border-color: var(--ti-mobile-checkbox-selected-border-color);
transform: translate(-50%, -50%) rotate(45deg) scaleY(1);
opacity: 1;
}
@ -114,7 +117,7 @@
position: absolute;
display: block;
border-radius: 2px;
background-color: var(--ti-mobile-checkbox-indeterminate-bg-color, #ffffff);
background-color: var(--ti-mobile-checkbox-indeterminate-bg-color);
height: 10px;
width: 10px;
left: 0;
@ -131,15 +134,20 @@
&.is-checked &__inner,
&.is-indeterminate &__inner {
background-color: var(--ti-mobile-checkbox-checked-bg-color, #4a79fe);
border-color: var(--ti-mobile-checkbox-checked-border-color, #4a79fe);
background-color: var(--ti-mobile-checkbox-checked-bg-color);
border-color: var(--ti-mobile-checkbox-checked-border-color);
}
&.is-disabled {
.checkbox-input-disabled(
var(--ti-mobile-checkbox-disabled-color, #dbdbdb),
var(--ti-mobile-checkbox-disabled-bg-color, #f5f5f5),
var(--ti-mobile-checkbox-disabled-border-color, #dbdbdb)
var(--ti-mobile-checkbox-disabled-text-color),
var(--ti-mobile-checkbox-disabled-bg-color),
var(--ti-mobile-checkbox-checked-disabled-bg-color),
var(--ti-mobile-checkbox-disabled-border-color)
);
}
&.icon-position-top &__input {
vertical-align: top;
}
}

View File

@ -1,17 +1,38 @@
:root {
--ti-mobile-checkbox-margin-right: 30px;
--ti-mobile-checkbox-bg-color: var(--ti-mobile-base-color-bg-3, #ffffff);
--ti-mobile-checkbox-border-radius: var(--ti-mobile-base-radius-large, 3px);
--ti-mobile-checkbox-border-color: var(--ti-mobile-base-color-common-8, #dbdbdb);
--ti-mobile-checkbox-size: 20px;
--ti-mobile-checkbox-checked-color: var(--ti-mobile-base-color-brand-1, #4a79fe);
--ti-mobile-checkbox-checked-border-color: var(--ti-mobile-base-color-brand-1, #4a79fe);
--ti-mobile-checkbox-checked-bg-color: var(--ti-mobile-base-color-brand-1, #4a79fe);
--ti-mobile-checkbox-selected-border-color: var(--ti-mobile-base-color-brand-6, #ffffff);
--ti-mobile-checkbox-indeterminate-bg-color: var(--ti-mobile-base-color-brand-6, #ffffff);
--ti-mobile-checkbox-color: var(--ti-mobile-base-color-common-5, #595959);
--ti-mobile-checkbox-font-size: 16px;
--ti-mobile-checkbox-disabled-color: var(--ti-mobile-base-color-common-8, #dbdbdb);
--ti-mobile-checkbox-disabled-bg-color: var(--ti-mobile-base-color-bg-1, #f5f5f5);
--ti-mobile-checkbox-disabled-border-color: var(--ti-mobile-base-color-common-8, #dbdbdb);
// 复选框图标宽度
--ti-mobile-checkbox-width: var(--ti-mobile-space-6x, 24px);
// 复选框图标高度
--ti-mobile-checkbox-height: var(--ti-mobile-checkbox-width, 24px);
// 复选框文本行高
--ti-mobile-checkbox-line-height: 22px;
// 复选框右边距
--ti-mobile-checkbox-margin-right: var(--ti-mobile-space-2x, 8px);
// 复选框图标与文本间距
--ti-mobile-checkbox-label-padding-left: var(--ti-mobile-space-2x, 8px);
// 复选框图标背景色
--ti-mobile-checkbox-bg-color: var(--ti-mobile-color-bg-container-1, #ffffff);
// 复选框图标圆角
--ti-mobile-checkbox-border-radius: var(--ti-mobile-border-radius-s, 4px);
// 复选框图标边框色
--ti-mobile-checkbox-border-color: var(--ti-mobile-color-border-default, #c2c2c2);
// 复选框选中图标边框色
--ti-mobile-checkbox-checked-border-color: var(--ti-mobile-color-icon-link, #1476ff);
// 复选框选中图标背景色
--ti-mobile-checkbox-checked-bg-color: var(--ti-mobile-color-icon-link, #1476ff);
// 复选框选中对勾图标色
--ti-mobile-checkbox-selected-border-color: var(--ti-mobile-color-icon-inverse, #ffffff);
// 复选框半选背景色
--ti-mobile-checkbox-indeterminate-bg-color: var(--ti-mobile-color-icon-inverse, #ffffff);
// 复选框文本色
--ti-mobile-checkbox-text-color: var(--ti-mobile-color-text-primary, #191919);
// 复选框字号
--ti-mobile-checkbox-font-size: var(--ti-mobile-font-size-m, 14px);
// 复选框禁用文本色
--ti-mobile-checkbox-disabled-text-color: var(--ti-mobile-color-text-disabled, #c2c2c2);
// 复选框禁用图标背景色
--ti-mobile-checkbox-disabled-bg-color: var(--ti-mobile-color-bg-container-2, #fafafa);
// 复选框勾选且禁用背景色
--ti-mobile-checkbox-checked-disabled-bg-color: var(--ti-mobile-color-bg-control-disabled-1, #dbdbdb);
// 复选框禁用图标边框色
--ti-mobile-checkbox-disabled-border-color: var(--ti-mobile-color-border-disabled, #dbdbdb);
}

View File

@ -10,6 +10,7 @@
*
*/
@import '../base/basic-var.less';
@import '../mixins/input.less';
@import '../mixins/common.less';
@import '../custom.less';
@ -18,36 +19,26 @@
@textarea-prefix-cls: ~'@{css-prefix}mobile-textarea';
@input-prefix-cls: ~'@{css-prefix}mobile-input';
@input-group-prefix-cls: ~'@{css-prefix}mobile-input-group';
@input-form-prefix-cls: ~'@{css-prefix}mobile-input-form';
.@{textarea-prefix-cls} {
position: relative;
display: inline-block;
width: 100%;
background-color: var(--ti-mobile-input-bg-color, #fff);
padding: 12px 16px;
&__count {
color: var(--ti-mobile-textarea-count-text-color, #999);
font-size: var(--ti-mobile-textarea-count-font-size, 12px);
margin-top: 4px;
text-align: right;
display: block;
}
line-height: var(--ti-mobile-input-line-height);
&__inner {
width: 100%;
height: var(--ti-mobile-textarea-inner-height, 96px);
padding: var(--ti-mobile-textarea-padding-vertical) var(--ti-mobile-textarea-padding-horizontal);
font-size: var(--ti-mobile-textarea-inner-font-size, 16px);
color: var(--ti-mobile-textarea-inner-text-color, #666);
padding: 0;
border: 0;
font-family: var(--ti-mobile-input-font-family);
color: var(--ti-mobile-textarea-inner-text-color);
border: var(--ti-mobile-input-border-width) solid var(--ti-mobile-input-border-color);
border-radius: var(--ti-mobile-input-radius);
display: block;
resize: none;
resize: vertical;
box-sizing: border-box;
transition: all 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
.placeholder(
@color: var(--ti-mobile-textarea-inner-placeholder-color, #ccc)
@color: var(--ti-mobile-textarea-inner-placeholder-color)
);
&:hover,
@ -56,42 +47,44 @@
}
}
&__title {
font-size: var(--ti-mobile-textarea-title-font-size, 16px);
color: var(--ti-mobile-textarea-title-text-color, #333);
margin-bottom: 8px;
&__count {
position: absolute;
right: var(--ti-mobile-textarea-padding-horizontal);
bottom: var(--ti-mobile-textarea-padding-vertical);
color: var(--ti-mobile-input-count-text-color);
font-size: var(--ti-mobile-input-count-font-size);
}
&__content {
margin-bottom: 8px;
&.is-focus {
border-color: var(--ti-mobile-input-border-color-active);
}
&.is-showlimit {
padding-bottom: 8px;
&.is-showlimit &__inner {
padding-bottom: calc(var(--ti-mobile-input-count-font-size) * 1.5 + var(--ti-mobile-textarea-padding-vertical));
}
&.is-showtitle &__inner {
height: var(--ti-mobile-textarea-showlimit-inner-height, 70px);
&.is-disabled {
.@{textarea-prefix-cls}__inner {
border-color: var(--ti-mobile-border-color-disabled);
background-color: var(--ti-mobile-input-bg-color-disabled);
color: var(--ti-mobile-input-text-color-disabled);
cursor: not-allowed;
.placeholder(@color: var(--ti-mobile-input-text-color-disabled));
}
}
&.is-showcontent &__inner {
height: var(--ti-mobile-textarea-showcontent-inner-height, 66px);
}
&.is-disabled &__inner {
background-color: var(--ti-mobile-input-bg-color-disabled, #f5f5f5);
color: var(--ti-mobile-input-color-disabled, #999);
cursor: not-allowed;
}
&.is-exceed &__count {
color: var(--ti-mobile-input-exceed-text-color, #f5222d);
&.is-exceed {
border-color: var();
&__count {
color: var(--ti-mobile-input-exceed-text-color);
}
}
}
.@{input-prefix-cls} {
position: relative;
width: 100%;
line-height: var(--ti-mobile-input-line-height);
&::-webkit-scrollbar {
z-index: 11;
@ -122,76 +115,78 @@
}
&.is-exceed &__suffix &__count {
color: var(--ti-mobile-input-exceed-text-color, #f5222d);
color: var(--ti-mobile-input-exceed-text-color);
}
&.is-disabled &__inner {
cursor: not-allowed;
color: var(--ti-mobile-input-color-disabled, #999);
background: var(--ti-mobile-input-bg-color-disabled, #f5f5f5);
}
&.is-disabled {
.@{input-prefix-cls}__wrapper {
border-color: var(--ti-mobile-border-color-disabled);
background: var(--ti-mobile-input-bg-color-disabled);
}
&.is-disabled &__icon {
cursor: not-allowed;
.@{input-prefix-cls}__inner {
cursor: not-allowed;
color: var(--ti-mobile-input-text-color-disabled);
.placeholder(@color: var(--ti-mobile-input-text-color-disabled));
}
&.@{css-prefix}svg {
&,
&:hover {
fill: var(--ti-mobile-input-color-disabled, #999);
.@{input-prefix-cls}__icon {
cursor: not-allowed;
&.@{css-prefix}svg {
&,
&:hover {
fill: var(--ti-mobile-input-icon-color-disabled);
}
}
}
.@{input-prefix-cls}__prefix,
.@{input-prefix-cls}__suffix {
.@{css-prefix}svg {
&,
&:hover {
fill: var(--ti-mobile-input-icon-color-disabled);
}
}
}
}
&.is-disabled &__prefix,
&.is-disabled &__suffix {
.@{css-prefix}svg {
&,
&:hover {
fill: var(--ti-mobile-input-color-disabled, #999);
}
}
&.@{input-group-prefix-cls}-prepend &__wrapper {
padding-left: 0;
}
& &__clear {
font-size: var(--ti-mobile-input-icon-font-size, 16px);
cursor: pointer;
transition: color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
&,
&:hover {
fill: var(--ti-mobile-input-color-disabled, #999);
}
&.@{input-group-prefix-cls}-append &__wrapper {
padding-right: 0;
}
& &__count {
height: 100%;
display: inline-flex;
&__wrapper {
display: flex;
align-items: center;
color: #909399;
font-size: 12px;
.@{input-prefix-cls}__count-inner {
background: var(--ti-mobile-input-bg-color, #fff);
line-height: initial;
display: inline-block;
}
height: var(--ti-mobile-input-height);
overflow: hidden;
border: var(--ti-mobile-input-border-width) solid var(--ti-mobile-input-border-color);
border-radius: var(--ti-mobile-input-radius);
background: var(--ti-mobile-input-bg-color);
}
&__inner {
flex: 1;
order: 3;
width: 100%;
height: 48px;
line-height: 48px;
font-size: 16px;
color: #666;
background: var(--ti-mobile-input-bg-color, #fff);
padding: 0 16px;
height: 100%;
padding: 0 var(--ti-mobile-input-padding-horizontal);
font-size: var(--ti-mobile-input-font-size);
font-family: var(--ti-mobile-input-font-family);
color: var(--ti-mobile-input-text-color);
border: 0;
outline: 0;
display: inline-block;
box-sizing: border-box;
-webkit-appearance: none;
appearance: none;
transition: all 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
.placeholder(@color: #ccc);
.placeholder(@color: var(--ti-mobile-input-placeholder-text-color));
&:hover,
&:focus,
@ -206,15 +201,54 @@
}
}
& &__clear {
font-size: var(--ti-mobile-input-icon-font-size, 16px);
cursor: pointer;
transition: color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
&,
&:hover {
fill: var(--ti-mobile-input-icon-color);
}
}
& &__count {
height: 100%;
display: inline-flex;
color: var(--ti-mobile-input-count-text-color);
font-size: var(--ti-mobile-input-count-font-size);
.@{input-prefix-cls}__count-inner {
background: var(--ti-mobile-input-bg-color, #fff);
line-height: initial;
display: inline-block;
}
}
&__prefix,
&__suffix {
position: absolute;
top: 50%;
transform: translateY(-50%);
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s;
text-align: center;
color: #d9d9d9;
line-height: calc(var(--ti-mobile-input-line-height, 30px) - 2px);
}
&__prefix {
padding-left: var(--ti-mobile-input-padding-horizontal);
order: 2;
transition: all 0.3s;
font-size: var(--ti-mobile-input-icon-font-size);
}
&__suffix {
order: 4;
padding-right: var(--ti-mobile-input-padding-horizontal);
transition: all 0.3s;
&:hover {
cursor: pointer;
}
}
&.is-active &__inner,
@ -222,36 +256,15 @@
outline: 0;
}
&__suffix {
right: 16px;
transition: all 0.3s;
pointer-events: none;
&:hover {
cursor: pointer;
}
}
&__suffix-inner {
pointer-events: all;
}
&__prefix {
left: 8px;
transition: all 0.3s;
font-size: var(--ti-mobile-input-icon-font-size, 16px);
}
&__icon {
height: 100%;
line-height: var(--ti-mobile-input-line-height, 30px);
text-align: center;
transition: all 0.3s;
font-size: var(--ti-mobile-input-icon-font-size, 16px);
font-size: var(--ti-mobile-input-icon-font-size);
&,
&:hover {
fill: var(--ti-mobile-input-color-disabled, #999);
fill: var(--ti-mobile-input-icon-color);
}
&:after {
@ -265,7 +278,7 @@
.svg-operationfaild {
&,
&:hover {
fill: var(--ti-mobile-input-icon-close-color, #bfbfbf);
fill: var(--ti-mobile-input-icon-color);
}
}
}
@ -274,15 +287,6 @@
pointer-events: none;
}
&-suffix &__inner {
padding-right: 48px;
}
&-prefix &__inner {
padding-left: 30px;
padding-right: 28px;
}
&-medium {
.input-size(var(--ti-mobile-input-medium-height, 42px));
}
@ -296,6 +300,10 @@
}
}
.@{input-prefix-cls}__title {
margin-bottom: var(--ti-mobile-input-title-margin-bottom);
}
.@{input-group-prefix-cls} {
line-height: normal;
display: inline-table;
@ -310,12 +318,9 @@
&__append,
&__prepend {
background-color: #f5f5f5;
color: #999;
padding: 0 20px;
width: 1px;
vertical-align: middle;
display: table-cell;
display: flex;
align-items: center;
height: 100%;
position: relative;
white-space: nowrap;
@ -341,39 +346,47 @@
color: inherit;
}
}
}
.@{input-form-prefix-cls} {
height: 48px;
line-height: 48px;
position: relative;
&__select {
display: flex;
justify-content: flex-end;
align-items: center;
width: 100%;
height: 100%;
background: var(--ti-mobile-input-bg-color, #fff);
&__prepend {
order: 1;
padding: 0 var(--ti-mobile-input-prepend-padding-horizontal);
color: var(--ti-mobile-input-prepend-text-color);
background-color: var(--ti-mobile-input-prepend-bg-color);
}
&__icon {
&__append {
order: 5;
padding: 0 var(--ti-mobile-input-append-padding-horizontal);
color: var(--ti-mobile-input-append-text-color);
background-color: var(--ti-mobile-input-append-bg-color);
}
}
.@{input-prefix-cls}__select {
display: flex;
align-items: center;
width: 100%;
height: 100%;
background: var(--ti-mobile-input-bg-color, #fff);
&-icon {
order: 5;
height: 20px;
margin-right: var(--ti-mobile-input-padding-horizontal);
line-height: 20px;
width: 20px;
margin-right: 16px;
font-size: 0;
transform-origin: center center;
transition: all linear 0.3s;
svg {
fill: #999;
fill: var(--ti-mobile-input-icon-color);
font-size: 20px;
vertical-align: text-bottom;
}
}
&__label {
&-label {
box-sizing: border-box;
width: 35%;
padding: 0 12px 0 16px;
@ -385,28 +398,15 @@
text-overflow: ellipsis;
}
&__input {
float: right;
}
&__tips {
width: 100%;
color: var(--ti-mobile-textarea-count-text-color, #999);
padding-top: 6px;
line-height: 20px;
}
&__error {
width: 100%;
height: 36px;
position: absolute;
overflow: hidden;
font-size: 13px;
line-height: 36px;
color: var(--ti-mobile-common-color-error-text-1, #e62222);
color: var(--ti-mobile-common-color-error-text-1);
text-overflow: ellipsis;
bottom: -36px;
background: var(--ti-mobile-input-form-bg-color-error, rgba(230, 34, 34, 0.04));
background: var(--ti-mobile-input-form-bg-color-error);
border-radius: 4px;
padding: 0px 12px;
&.align-right {
@ -426,6 +426,11 @@
animation: rotating 2s linear infinite;
}
.@{input-prefix-cls}__tips {
margin-top: var(--ti-mobile-input-tips-margin-top);
font-size: var(--ti-mobile-input-tips-font-size);
}
@keyframes rotating {
0% {
transform: rotateZ(0deg);

View File

@ -1,23 +1,91 @@
:root {
--ti-mobile-input-bg-color: var(--ti-mobile-base-color-light, #fff);
--ti-mobile-input-line-height: var(--ti-mobile-base-size-height-minor, 30px);
--ti-mobile-input-medium-height: var(--ti-mobile-base-size-height-medium, 42px);
--ti-mobile-input-small-height: var(--ti-mobile-base-size-height-small, 36px);
--ti-mobile-input-mini-height: var(--ti-mobile-base-size-height-mini, 24px);
--ti-mobile-input-color-disabled: var(--ti-mobile-base-color-placeholder, #999);
--ti-mobile-input-bg-color-disabled: var(--ti-mobile-base-color-selected-background, #f5f5f5);
--ti-mobile-input-exceed-text-color: var(--ti-mobile-base-color-danger-normal, #f5222d);
--ti-mobile-input-icon-font-size: 16px;
--ti-mobile-input-icon-close-color: var(--ti-mobile-base-color-primary-disabled, #bfbfbf);
--ti-mobile-textarea-count-text-color: var(--ti-mobile-base-color-placeholder, #999);
--ti-mobile-textarea-count-font-size: var(--ti-mobile-base-font-size, 12px);
--ti-mobile-textarea-inner-height: 96px;
--ti-mobile-textarea-inner-font-size: 16px;
--ti-mobile-textarea-inner-text-color: var(--ti-mobile-base-color-secondary, #666);
--ti-mobile-textarea-inner-placeholder-color: #ccc;
--ti-mobile-textarea-title-font-size: 16px;
--ti-mobile-textarea-title-text-color: var(--ti-mobile-base-color-info-normal, #333);
--ti-mobile-textarea-showlimit-inner-height: 70px;
--ti-mobile-textarea-showcontent-inner-height: 66px;
--ti-mobile-input-form-bg-color-error: rgba(230, 34, 34, 0.04);
// 高度
--ti-mobile-input-height: 40px;
// 水平内边距
--ti-mobile-input-padding-horizontal: var(--ti-mobile-space-3x, 12px);
// 字号
--ti-mobile-input-font-size: var(--ti-mobile-font-size-m, 14px);
// 字族
--ti-mobile-input-font-family: var(--ti-mobile-font-family);
// 行高
--ti-mobile-input-line-height: var(--ti-mobile-line-height-default, 1.5);
// 字体色
--ti-mobile-input-text-color: var(--ti-mobile-color-text-primary, #191919);
// 禁用字体色
--ti-mobile-input-text-color-disabled: var(--ti-mobile-color-text-disabled, #c2c2c2);
// 禁用图标色
--ti-mobile-input-icon-color-disabled: var(--ti-mobile-color-icon-disabled, #c2c2c2);
// 禁用背景色
--ti-mobile-input-bg-color-disabled: var(--ti-mobile-color-bg-disabled, #f0f0f0);
// 边框宽度
--ti-mobile-input-border-width: var(--ti-mobile-border-width-1, 1px);
// 边框色
--ti-mobile-input-border-color: var(--ti-mobile-color-border-default, #c2c2c2);
// 输入时边框色
--ti-mobile-input-border-color-active: var(--ti-mobile-color-border-active, #191919);
// 边框禁用色
--ti-mobile-border-color-disabled: var(--ti-mobile-color-border-disabled, #dbdbdb);
// 圆角
--ti-mobile-input-radius: var(--ti-mobile-border-radius-m, 8px);
// 背景色
--ti-mobile-input-bg-color: var(--ti-mobile-color, #fff);
// 占位符字体色
--ti-mobile-input-placeholder-text-color: var(--ti-mobile-color-text-placeholder, #808080);
// 占位符字重
--ti-mobile-input-placeholder-font-weight: var(--ti-mobile-font-weight-medium, 500);
// medium尺寸高度
--ti-mobile-input-medium-height: 42px;
// small尺寸高度
--ti-mobile-input-small-height: 36px;
// mini尺寸高度
--ti-mobile-input-mini-height: 24px;
// 字数提示字体色
--ti-mobile-input-count-text-color: var(--ti-mobile-color-text-placeholder, #808080);
// 字数提示字号
--ti-mobile-input-count-font-size: var(--ti-mobile-font-size-s, 12px);
// 超出文本提示语字体色
--ti-mobile-input-exceed-text-color: var(--ti-mobile-color-error, #f23030);
// 图标颜色
--ti-mobile-input-icon-color: var(--ti-mobile-color-icon-default, #808080);
// 图标尺寸
--ti-mobile-input-icon-font-size: var(--ti-mobile-font, 20px);
// prepend内容字体色
--ti-mobile-input-prepend-text-color: var(--ti-mobile-color-text-secondary, #595959);
// prepend内容背景色
--ti-mobile-input-prepend-bg-color: var(--ti-mobile-color-bg-default, #f5f5f5);
// prepend内容水平内边距
--ti-mobile-input-prepend-padding-horizontal: var(--ti-mobile-space-5x, 20px);
// append内容字体色
--ti-mobile-input-append-text-color: var(--ti-mobile-color-text-secondary, #595959);
// append内容背景色
--ti-mobile-input-append-bg-color: var(--ti-mobile-color-bg-default, #f5f5f5);
// append内容水平内边距
--ti-mobile-input-append-padding-horizontal: var(--ti-mobile-space-5x, 20px);
// prefix内容右边距
--ti-mobile-input-prefix-padding-right: var(--ti-mobile-space-2x, 8px);
// suffix内容左边距
--ti-mobile-input-suffix-padding-left: var(--ti-mobile-space-2x, 8px);
// 标题下边距
--ti-mobile-input-title-margin-bottom: var(--ti-mobile-space-2x, 8px);
// 提示信息字号
--ti-mobile-input-tips-font-size: var(--ti-mobile-font-size-s, 12px);
// 提示信息上边距
--ti-mobile-input-tips-margin-top: var(--ti-mobile-space-2x, 8px);
// 文本域垂直内边距
--ti-mobile-textarea-padding-vertical: var(--ti-mobile-space-2x, 8px);
// 文本域水平内边距
--ti-mobile-textarea-padding-horizontal: var(--ti-mobile-space-4x, 16px);
// 文本域字号
--ti-mobile-textarea-inner-font-size: var(--ti-mobile-font-size-m, 14px);
// 文本域字体色
--ti-mobile-textarea-inner-text-color: var(--ti-mobile-color-text-primary, #191919);
// 文本域占位符字体色
--ti-mobile-textarea-inner-placeholder-color: var(--ti-mobile-color-text-placeholder, #808080);
// 文本域标题字号
--ti-mobile-textarea-title-font-size: var(--ti-mobile-font-size-l, 16px);
// 文本域标题字体色
--ti-mobile-textarea-title-text-color: var(--ti-mobile-color-text-primary, #191919);
// 错误状态背景色
--ti-mobile-input-form-bg-color-error: var(--ti-mobile-color-error-subtle, #fce3e1);
}

View File

@ -0,0 +1,59 @@
/**
* Copyright (c) 2022 - present TinyVue Authors.
* Copyright (c) 2022 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
@import '../custom.less';
@import '../base/basic-var.less';
@import './vars.less';
@mask-prefix-cls: ~'@{css-prefix}mobile-mask';
.@{mask-prefix-cls} {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: var(--tiny-mobile-mask-bg-color);
height: 100%;
}
.mask-fade-enter-active {
animation: mask-fade-in 0.3s;
}
.mask-fade-leave-active {
animation: mask-fade-out 0.3s;
}
@keyframes mask-fade-in {
0% {
transform: translate3d(0, -20px, 0);
opacity: 0;
}
100% {
transform: translate3d(0, 0, 0);
opacity: 1;
}
}
@keyframes mask-fade-out {
0% {
transform: translate3d(0, 0, 0);
opacity: 1;
}
100% {
transform: translate3d(0, -20px, 0);
opacity: 0;
}
}

View File

@ -0,0 +1,4 @@
:root {
// 遮罩层背景色
--tiny-mobile-mask-bg-color: var(--ti-color-bg-mask);
}

View File

@ -14,9 +14,9 @@
@checkbox-prefix-cls: ~'@{css-prefix}mobile-checkbox';
.checkbox-input-disabled(@color, @bgcolor, @border-color) {
.checkbox-input-disabled(@color, @bg-color, @checked-bg-color, @border-color) {
.@{checkbox-prefix-cls}__inner {
background-color: @bgcolor;
background-color: @bg-color;
border-color: @border-color;
cursor: not-allowed;
}
@ -24,14 +24,14 @@
&.is-checked {
.@{checkbox-prefix-cls}__inner,
.@{checkbox-prefix-cls}__inner:hover {
background-color: @border-color;
background-color: @checked-bg-color;
}
}
&.is-indeterminate {
.@{checkbox-prefix-cls}__inner,
.@{checkbox-prefix-cls}__inner:hover {
background-color: @bgcolor;
background-color: @bg-color;
&::before {
background-color: @border-color;

View File

@ -154,6 +154,7 @@
"@opentiny/vue-locales": "workspace:~",
"@opentiny/vue-logon-user": "workspace:~",
"@opentiny/vue-logout": "workspace:~",
"@opentiny/vue-mask": "workspace:~",
"@opentiny/vue-menu": "workspace:~",
"@opentiny/vue-message": "workspace:~",
"@opentiny/vue-milestone": "workspace:~",

View File

@ -75,7 +75,19 @@ export const alertProps = {
type: Boolean,
default: false
},
customClass: [String, Object, Array]
customClass: [String, Object, Array],
offset: {
type: [Number, String],
default: 0
},
autoHide: {
type: Boolean,
default: false
},
target: {
type: String,
default: ''
}
}
const aaa = {}

View File

@ -13,7 +13,8 @@
<transition name="tiny-mobile-alert-fade">
<div
v-if="state.show"
:class="['tiny-mobile-alert', 'tiny-mobile-alert--' + type, 'tiny-mobile-alert--' + size, 'is-center']"
:class="state.alertClass"
:style="state.alertStyle"
>
<component v-if="showIcon" :is="state.getIcon" class="tiny-mobile-alert__icon" />
<div :class="['tiny-mobile-alert__content', { 'is-hideicon': !showIcon }]">
@ -37,7 +38,7 @@ import type { IAlertApi } from '@opentiny/vue-renderless/types/alert.type'
import '@opentiny/vue-theme-mobile/alert/index.less'
export default defineComponent({
props: [...props, 'icon', 'type', 'size', 'description', 'closable', 'showIcon', 'closeText', 'duration'],
props: [...props, 'icon', 'type', 'size', 'description', 'closable', 'showIcon', 'closeText', 'duration', 'offset', 'autoHide', 'target', 'center'],
components: {
IconClose: iconClose(),
IconSuccess: iconSuccess(),

View File

@ -0,0 +1,9 @@
import ChartBar from './src/chart-bar.vue'
ChartBar.install = function (Vue: any) {
Vue.component(ChartBar.name, ChartBar)
}
export { ChartBar }
export default ChartBar

View File

@ -0,0 +1,18 @@
{
"name": "@opentiny/vue-chart-bar-beta",
"version": "3.7.0",
"description": "",
"main": "lib/index.js",
"module": "index.ts",
"sideEffects": false,
"type": "module",
"devDependencies": {},
"scripts": {
"build": "pnpm -w build:ui $npm_package_name",
"//postversion": "pnpm build"
},
"dependencies": {
"@opentiny/vue-chart-core-beta": "workspace:~"
},
"license": "MIT"
}

View File

@ -0,0 +1,38 @@
<template>
<div class="hui-chart chart-bar" ref="chartRef" :style="{ height: height }">
</div>
</template>
<script>
import { histogram } from './histogram'
import Core from '@opentiny/vue-chart-core-beta'
export default {
name: 'ChartBar',
mixins: [Core],
data() {
return {
iChartName: 'BarChart',
option: {
},
}
},
methods: {
updateChart() {
let { columns = [], rows = [] } = this.data
const extra = {
tooltipVisible: this.tooltipVisible,
legendVisible: this.legendVisible,
extend: this.extend
}
const option = histogram(columns, rows, this.settings, extra, false);
this.option = {
smooth: true,
...option,
direction: 'horizontal',
}
}
},
}
</script>

View File

@ -0,0 +1,266 @@
import { getFormatted, cloneDeep, getStackMap, get, set } from '@opentiny/vue-chart-core-beta/common/util'
import { isNull } from '@opentiny/vue-chart-core-beta/common/type'
import { getRows, getTooltip } from '@opentiny/vue-chart-core-beta/utils/options'
const VALUE_AXIS_OPACITY = 0.5
const getBarDimAxis = (args) => {
const { innerRows, dimAxisName, dimension, axisVisible, dimAxisType, dims } = args
return dimension.map((item) => ({
type: 'category',
name: dimAxisName,
nameLocation: 'middle',
nameGap: 22,
data: dimAxisType === 'value' ? getValueAxisData(dims) : innerRows.map((row) => row[item]),
axisLabel: {
formatter(value) {
return String(value)
}
},
show: axisVisible
}))
}
const getBarMeaAxis = (args) => {
const { axisVisible, digit, max, meaAxisName = [], meaAxisType, min, scale } = args
const meaAxisBase = { type: 'value', axisTick: { show: false }, show: axisVisible }
let { meaAxis = [], i = 0, formatter } = {}
for (; i < 2; i++) {
if (meaAxisType[i]) {
formatter = factoryFmt({ meaAxisType, i, digit })
meaAxis[i] = { ...meaAxisBase, axisLabel: { formatter } }
} else {
meaAxis[i] = { ...meaAxisBase }
}
Object.assign(meaAxis[i], {
max: max[i] || null,
min: min[i] || null,
name: meaAxisName[i] || '',
scale: scale[i] || false
})
}
return meaAxis
}
const factoryFmt =
({ meaAxisType, i, digit }) =>
(val) =>
getFormatted(val, meaAxisType[i], digit)
const getLegend = (args) => {
const { legendName } = args
let legendBase = {
show: true
}
let formatter = function (name) {
return !legendName[name] ? name : legendName[name]
}
return {
...legendBase,
formatter
}
}
const getDims = (rows, dimension) => rows.map((row) => row[dimension[0]])
const getValueAxisData = (dims) => {
const max = Math.max(...dims)
const min = Math.min(...dims)
let { result = [], i = min } = {}
for (; i <= max; i++) {
result.push(i)
}
return result
}
const getValueData = (seriesTemp, dims) => {
const max = Math.max(...dims)
const min = Math.min(...dims)
let { result = [], i = min, index } = {}
for (; i <= max; i++) {
index = dims.indexOf(i)
result.push(~index ? seriesTemp[index] : null)
}
return result
}
const getBarSeries = (args) => {
const { axisSite, barGap, dimAxisType, dims, innerRows, isHistogram, itemStyle } = args
const { label, labelMap, metrics, opacity, showLine = [], stack } = args
let { secondAxis, secondDimAxisIndex, series = [], seriesTemp = {}, stackMap, stackNum = 0 } = {}
secondAxis = (isHistogram ? axisSite?.right : axisSite?.top) || []
secondDimAxisIndex = isHistogram ? 'yAxisIndex' : 'xAxisIndex'
stackMap = stack && getStackMap(stack)
metrics.forEach((item) => (seriesTemp[item] = []))
innerRows.forEach((row) => metrics.forEach((item) => seriesTemp[item].push(row[item])))
series = Object.keys(seriesTemp).map((item) => {
let name = !isNull(labelMap[item]) ? labelMap[item] : item
let type = ~showLine.indexOf(item) ? 'line' : 'bar'
let axisIndex = ~secondAxis.indexOf(item) ? '1' : '0'
let seriesItem = { name, type, [secondDimAxisIndex]: axisIndex }
const defaultItemStyle = {}
stack && stackMap[item] && (seriesItem.stack = stackMap[item])
if (Object.keys(stack).length) {
// 堆叠图
if (stackNum === Object.keys(stackMap).length - 1 || isNull(seriesItem.stack)) {
seriesItem.itemStyle = Object.assign(defaultItemStyle, seriesItem.itemStyle)
}
if (!isNull(seriesItem.stack)) {
stackNum++
}
seriesItem.itemStyle = { borderWidth: 2, borderColor: 'transparent', ...seriesItem.itemStyle }
} else {
// 非堆叠图
}
itemStyle && (seriesItem.itemStyle = itemStyle)
let itemOpacity = opacity || get(seriesItem, 'itemStyle.opacity')
dimAxisType === 'value' && Object.assign(seriesItem, { barGap, barCategoryGap: '1%' })
dimAxisType === 'value' && isNull(itemOpacity) && (itemOpacity = VALUE_AXIS_OPACITY)
!isNull(itemOpacity) && set(seriesItem, 'itemStyle.opacity', itemOpacity)
return seriesItem
})
return series.length ? series : false
}
const getDataValue = (data, dimension, metrics, innerRows, dims) => {
let dimensionData = dimension[0]
let dataTemp = {}
data.forEach((item, index) => {
dataTemp[item[dimensionData]] = item
})
let dataItemTemp = {}
metrics.forEach((item, index) => {
dataItemTemp[item] = null
})
const max = Math.max(...dims)
const min = Math.min(...dims)
let { result = [], i = min, index } = {}
for (; i <= max; i++) {
index = dims.indexOf(i)
result.push(~index ? dataTemp[i] : { [dimensionData]: i, ...dataItemTemp })
}
return result
}
export const histogram = (columns, rows, settings, extra, isHistogram = true) => {
const innerRows = cloneDeep(rows)
const { axisSite = {}, dimension = [columns[0]], axisLabel = {}, axisVisible = true } = settings
const {
digit = 2,
dataOrder = false,
scale = [false, false],
min = [null, null],
max = [null, null],
stack = {}
} = settings
const { tooltipVisible, legendVisible } = extra
const { labelMap = {}, legendName = {}, label, itemStyle = {}, showLine, barGap = '-100%', opacity } = settings
let { metrics = columns.slice(), meaAxisType, dimAxisType, meaAxisName, dimAxisName = true, dims } = {}
if (dataOrder) {
let { label, order } = dataOrder
if (label && order) {
innerRows.sort((a, b) => (order === 'desc' ? a[label] - b[label] : b[label] - a[label]))
}
}
let xAxis = {}
let yAxis = {}
dims = getDims(innerRows, dimension)
if (isHistogram) {
if (axisSite.right && axisSite.left) {
metrics = axisSite.left.concat(axisSite.right)
} else if (settings.metrics) {
metrics = settings.metrics
} else if (axisSite.left && !axisSite.right) {
metrics = axisSite.left
} else {
metrics.splice(columns.indexOf(dimension[0]), 1)
}
dimAxisType = settings.xAxisType || 'category'
meaAxisType = settings.yAxisType || ['normal', 'normal']
dimAxisName = settings.xAxisName || ''
meaAxisName = settings.yAxisName || []
xAxis = getBarDimAxis({ innerRows, dimAxisName, dimension, axisVisible, dimAxisType, dims })
yAxis = getBarMeaAxis({ meaAxisName, meaAxisType, axisVisible, digit, scale, min, max })
} else {
if (axisSite.bottom && axisSite.top) {
metrics = axisSite.top.concat(axisSite.bottom)
} else if (!axisSite.right && axisSite.bottom) {
metrics = axisSite.bottom
} else if (settings.metrics) {
metrics = settings.metrics
} else {
metrics.splice(columns.indexOf(dimension[0]), 1)
}
dimAxisType = settings.yAxisType || 'category'
meaAxisType = settings.xAxisType || ['normal', 'normal']
dimAxisName = settings.yAxisName || ''
xAxis = getBarDimAxis({ innerRows, dimAxisName, dimension, axisVisible, dimAxisType, dims })
yAxis = getBarMeaAxis({ axisVisible, meaAxisType, meaAxisName, scale, digit, max, min })
}
if (opacity) {
const itemStyleBase = {
opacity
}
Object.assign(itemStyle, itemStyleBase)
}
let data = getRows({ columns, metrics, labelMap, rows: innerRows, dimension })
if (dimAxisType === 'value') {
data = getDataValue(data, dimension, metrics, innerRows, dims)
}
const lineDataName = showLine ? [...showLine] : []
const legend = legendVisible ? getLegend({ legendName, metrics, labelMap }) : { show: false }
const tooltip = tooltipVisible ? getTooltip({ axisSite, yAxisType: meaAxisType }) : { show: false }
const tipHtml = tooltip.formatter
let args = { innerRows, metrics, stack, axisSite, isHistogram, labelMap, itemStyle, label }
Object.assign(args, { showLine, dimAxisType, dimension, barGap, opacity, dims })
let options = {
data,
itemStyle,
tipHtml,
lineDataName,
legend,
tooltip,
yAxis,
xAxis,
label,
stack,
series: getBarSeries(args)
}
if (typeof options.stack === 'object' && options.stack !== null && Object.keys(options.stack).length > 0) {
options.type = 'stack'
}
return options
}

View File

@ -0,0 +1,58 @@
import core from './core'
import Register from './register'
import Theme from './feature/theme'
import { isFunction } from './util/type'
import { mergeExtend } from './util/merge'
import readScreen from './feature/readScreen'
import mediaScreen from './feature/mediaScreen'
// 图表核心对象,通过 Register 全量引入图表给 HuiCharts 渲染,打包容量较大
export default class HuiCharts extends core {
constructor() {
super()
// 图表名称
this.chartName
}
// 传入简化后的icharts-option
setSimpleOption(chartName, iChartOption, plugins = {}, isInit = true) {
if (isInit) {
Theme.setDefaultTheme(iChartOption.theme)
this.mediaScreenObserver && this.mediaScreenObserver.setInitOption(iChartOption)
}
if (iChartOption.readScreen) {
readScreen(this.dom, iChartOption.readScreen)
}
if (isFunction(chartName)) {
this.redirectSelfChart(chartName, iChartOption)
return
}
this.plugins = plugins
this.chartName = chartName
this.iChartOption = iChartOption
const ChartClass = this.getChartClass(chartName)
this.ichartsIns = new ChartClass(iChartOption, this.echartsIns, this.plugins)
this.eChartOption = this.ichartsIns.getOption()
mergeExtend(this.iChartOption, this.eChartOption)
}
// 获取图表类
getChartClass(name) {
return Register.getRegisteredComp(name)
}
// 开启响应式布局(类媒体查询效果)
mediaScreen(dom, screenOption) {
this.mediaScreenObserver = new mediaScreen(dom, screenOption, (option) => {
this.setSimpleOption(this.chartName, option, this.plugins, false)
this.render()
})
}
// 图表刷新,包括刷新配置和数据
refresh(iChartOption) {
this.iChartOption = iChartOption
this.setSimpleOption(this.chartName, iChartOption, this.plugins)
this.render()
}
}

View File

@ -0,0 +1,29 @@
import Theme from '../../feature/theme'
import proxy from '../../util/proxy'
function getChartToken() {
const {
itemStyle: { borderWidth, borderColor, borderRadius, color },
label: { color: labelColor, fontSize },
barWidth
} = Theme.config.BarChart
const {
colorState: { errorColor }
} = Theme.config
return {
borderWidth,
borderColor,
borderRadius,
color,
labelColor,
fontSize,
barWidth,
errorColor
}
}
const chartToken = proxy(getChartToken)
export default chartToken

View File

@ -0,0 +1,84 @@
import defendXSS from '../../util/defendXSS'
import chartToken from './chartToken'
/**
* ,
*/
export function setStack(baseOption, iChartOption, legendData, seriesData) {
const type = iChartOption.type
if (type && type === 'stack') {
// 添加堆叠图空白缝隙
baseOption.series.forEach((item) => {
item.itemStyle.borderWidth = chartToken.borderWidth
item.itemStyle.borderColor = chartToken.borderColor
})
// 柱子圆角,上层数值为空时,圆角递进到下层
const direction = iChartOption.direction
iChartOption.data.forEach((item, i) => {
for (let j = legendData.length - 1; j >= 0; j--) {
const name = legendData[j]
if (item[name]) {
seriesData[name][i] = {
value: seriesData[name][i],
itemStyle: {
borderRadius:
direction === 'horizontal'
? [0, chartToken.borderRadius, chartToken.borderRadius, 0]
: [chartToken.borderRadius, chartToken.borderRadius, 0, 0]
}
}
break
}
}
})
}
}
/**
* y轴的label都转为正数
* tooltip
*/
export function setDoubleSides(baseOption, iChartOption) {
const type = iChartOption.type
if (type && type === 'double-sides') {
const yAxis = baseOption.yAxis
yAxis.forEach((item) => {
item.axisLabel.formatter = (value) => {
return Math.abs(value)
}
})
if (!baseOption.tooltip.formatter) {
baseOption.tooltip.formatter = (params, ticket, callback) => {
let html = ''
params.forEach((item, index) => {
if (index === 0) {
html += `<div style="margin-bottom:4px;">${defendXSS(item.name)}</div>`
}
html += `<div>
<span style="display:inline-block;width:10px;height:10px;border-radius:5px;background-color:${defendXSS(
item.color
)};"></span>
<span style="margin-left:5px;color:#000000">
<span style="display:inline-block; margin-right:8px;min-width:48px;">${defendXSS(
item.seriesName
)}</span>
<span style="font-weight:bold">${defendXSS(item.value ? Math.abs(item.value) : '-')}</span>
</span>
</div>`
})
return html
}
}
}
}
/**
*
*/
export function setDirection(baseOption, direction) {
if (direction && direction === 'horizontal') {
const temp = baseOption.xAxis
baseOption.xAxis = baseOption.yAxis
baseOption.yAxis = temp
}
}

View File

@ -0,0 +1,614 @@
import merge from '../../util/merge'
import defendXSS from '../../util/defendXSS'
import { getColor } from '../../util/color'
import cloneDeep from '../../util/cloneDeep'
import { isArray, isNumber } from '../../util/type'
import { getMarkLineDefault } from '../../option/config/mark'
import chartToken from './chartToken'
export const seriesInit = () => {
return {
label: {
show: false,
color: chartToken.labelColor,
fontSize: chartToken.fontSize
},
// 数据
data: [],
// 柱形
type: 'bar',
// 柱条宽度
barWidth: chartToken.barWidth,
// 柱间距离
barGap: '60%',
// 阈值线
markLine: null,
// 峰值标志
markPoint: null,
// 柱形的每个样式配置项
itemStyle: {
borderRadius: [chartToken.borderRadius, chartToken.borderRadius, 0, 0]
}
}
}
function handleWaterFall(type, seriesUnit) {
if (type && type === 'water-fall') {
// 调整堆叠柱子圆角
seriesUnit.itemStyle.borderRadius = [
chartToken.borderRadius,
chartToken.borderRadius,
chartToken.borderRadius,
chartToken.borderRadius
]
// 瀑布图最有有一个总体数据
seriesUnit.data.push(
seriesUnit.data.reduce(function (prev, curr) {
const n = Number(curr) || 0
return prev + n
}, 0)
)
}
}
function handleRange(type, seriesUnit) {
if (type && type === 'range') {
// 调整堆叠柱子圆角
seriesUnit.itemStyle.borderRadius = [
chartToken.borderRadius,
chartToken.borderRadius,
chartToken.borderRadius,
chartToken.borderRadius
]
}
}
/**
* echarts所需要的series
* @param {} seriesData
* @param {} legendData
* @param {} theme
* @param {} isArea
* @param {线} isSmooth
* @param {线} isStep
* @param {线} markLine
* @param {} markPoint
* @param {} colors
* @returns
*/
export function setSeries(seriesData, legendData, iChartOption) {
// 柱状图类型
const type = iChartOption.type
// 柱状图方向
const direction = iChartOption.direction
// 覆盖用户传入的itemStyle
const seriesInit_ = handleItemStyle(direction, iChartOption.itemStyle)
// 拼装series
const series = []
legendData.forEach((legend, index) => {
const seriesUnit = cloneDeep(seriesInit_)
// 数值显示
handleLabel(seriesUnit, iChartOption, index)
// 聚焦效果
handleFocus(seriesUnit, iChartOption)
// 数据 / 数据名称
seriesUnit.name = legend
seriesUnit.data = seriesData[legend]
// 阈值线
handleMarkLine(seriesUnit, iChartOption, direction)
// 堆叠图
handleStack(type, seriesUnit, index, legendData, iChartOption)
// 双向图
handleBothSides(type, seriesUnit, direction, index, legendData)
// 数据均为正数的双向图
handleDoubleSides(type, seriesUnit, index, legendData)
// 瀑布图
handleWaterFall(type, seriesUnit)
// 区间图
handleRange(type, seriesUnit)
// 包含图
handleContain(type, seriesUnit)
series.push(seriesUnit)
})
// 配置多个series的y轴index
handleYaxis(series, iChartOption.yAxis)
return series
}
function handleItemStyle(direction, itemStyle) {
const seriesInit_ = cloneDeep(seriesInit())
if (direction && direction === 'horizontal') {
seriesInit_.itemStyle.borderRadius = [0, chartToken.borderRadius, chartToken.borderRadius, 0]
}
if (itemStyle?.barMinHeight) {
seriesInit_.barMinHeight = itemStyle.barMinHeight
}
if (itemStyle?.barWidth) {
seriesInit_.barWidth = itemStyle.barWidth
}
if (itemStyle?.barGap) {
seriesInit_.barGap = itemStyle.barGap
}
if (itemStyle?.color) {
seriesInit_.itemStyle.color = itemStyle.color
}
merge(seriesInit_.itemStyle, itemStyle)
return seriesInit_
}
function handleLabel(seriesUnit, iChartOption, index) {
const label = iChartOption.label
let labelOption
if (label && isArray(label)) {
labelOption = label[index]
} else {
labelOption = label
}
if (labelOption && labelOption.show) {
merge(seriesUnit.label, labelOption)
seriesUnit.label.show = true
seriesUnit.label.offset = labelOption.offset || [0, 0]
seriesUnit.label.position = labelOption.position || 'inside'
seriesUnit.label.formatter = labelOption.formatter
}
}
function handleMarkLine(seriesUnit, iChartOption, direction) {
const name = seriesUnit.name
const theme = iChartOption.theme
const markLine = iChartOption.markLine
const isTopMarkLine = markLine && markLine.top && !(markLine.topUse && !markLine.topUse.includes(name))
const isBottomMarkLine = markLine && markLine.bottom && !(markLine.bottomUse && !markLine.bottomUse.includes(name))
if (isTopMarkLine || isBottomMarkLine) {
seriesUnit.markLine = cloneDeep(getMarkLineDefault())
merge(seriesUnit.markLine, markLine)
seriesUnit.markLine.lineStyle.color = markLine.color || chartToken.errorColor
}
if (isTopMarkLine) {
if (direction && direction === 'horizontal') {
seriesUnit.markLine.data.push({ xAxis: markLine.top })
} else {
seriesUnit.markLine.data.push({ yAxis: markLine.top })
}
}
if (isBottomMarkLine) {
if (direction && direction === 'horizontal') {
seriesUnit.markLine.data.push({ xAxis: markLine.bottom })
} else {
seriesUnit.markLine.data.push({ yAxis: markLine.bottom })
}
}
}
function handleFocus(seriesUnit, iChartOption) {
if (iChartOption.focus) {
seriesUnit.emphasis = {
focus: 'series',
blurScope: 'global'
}
}
}
function handleStack(type, seriesUnit, index, legendData, iChartOption) {
if (type && type === 'stack') {
const stack = iChartOption.stack
if (stack) {
for (const name in stack) {
if (Object.hasOwnProperty.call(stack, name)) {
const stackArray = stack[name]
const seriesName = seriesUnit.name
const stackIndex = stackArray.indexOf(seriesName)
if (stackIndex !== -1) {
seriesUnit.stack = name
if (stackIndex + 1 < stackArray.length) {
delete seriesUnit.itemStyle.borderRadius
}
}
break
}
}
} else {
seriesUnit.stack = 'stack'
if (index !== legendData.length - 1) {
delete seriesUnit.itemStyle.borderRadius
}
}
}
}
function handleBothSides(type, seriesUnit, direction, index, legendData) {
if (type && (type === 'both-sides' || type === 'double-sides')) {
seriesUnit.stack = 'stack'
// 调整堆叠柱子圆角
if (direction && direction === 'horizontal') {
if (index === 0) {
seriesUnit.itemStyle.borderRadius = [0, chartToken.borderRadius, chartToken.borderRadius, 0]
}
if (index === legendData.length - 1) {
seriesUnit.itemStyle.borderRadius = [chartToken.borderRadius, 0, 0, chartToken.borderRadius]
}
} else {
if (index === 0) {
seriesUnit.itemStyle.borderRadius = [chartToken.borderRadius, chartToken.borderRadius, 0, 0]
}
if (index === legendData.length - 1) {
seriesUnit.itemStyle.borderRadius = [0, 0, chartToken.borderRadius, chartToken.borderRadius]
}
}
}
}
function handleDoubleSides(type, seriesUnit, index, legendData) {
if (type && type === 'double-sides') {
if (index === legendData.length - 1) {
seriesUnit.data = seriesUnit.data.map((item) => {
if (isNumber(item)) {
return -1 * item
} else {
return item
}
})
}
}
}
function handleContain(type, seriesUnit) {
if (type && type === 'contain') {
seriesUnit.barGap = '-100%'
}
}
function handleColorStops(percent, originColor, markLineColor) {
const colorStops = [
{
offset: 0,
color: markLineColor || chartToken.errorColor
},
{
offset: percent,
color: markLineColor || chartToken.errorColor
},
{
offset: percent + 0.001,
color: originColor
},
{
offset: 1,
color: originColor
}
]
return colorStops
}
function handleTopObj(d, direction, percent, originColor, markLineColor) {
const topObj = {
value: d,
itemStyle: {
color: {
type: 'linear',
x: direction === 'horizontal' ? 1 : 0,
y: direction === 'horizontal' ? 0 : 0,
x2: direction === 'horizontal' ? 0 : 0,
y2: direction === 'horizontal' ? 0 : 1,
colorStops: handleColorStops(percent, originColor, markLineColor)
}
}
}
return topObj
}
function handleBottomObj(d, direction, percent, originColor, markLineColor) {
const bottomObj = {
value: d,
itemStyle: {
color: {
type: 'linear',
x: direction === 'horizontal' ? 0 : 0,
y: direction === 'horizontal' ? 0 : 1,
x2: direction === 'horizontal' ? 1 : 0,
y2: direction === 'horizontal' ? 0 : 0,
colorStops: handleColorStops(percent, originColor, markLineColor)
}
}
}
return bottomObj
}
const colorStopsOrigin = [
{ offset: 0, color: chartToken.errorColor },
{ offset: 1, color: chartToken.errorColor }
]
function handleColorStopsTop(originColor, bottomPercent) {
const colorStops = [
{ offset: 0, color: originColor },
{ offset: bottomPercent, color: originColor },
{ offset: bottomPercent + 0.0001, color: chartToken.errorColor },
{ offset: 1, color: chartToken.errorColor }
]
return colorStops
}
function handleColorStopsBottom(originColor, topPercent) {
const colorStops = [
{ offset: 0, color: chartToken.errorColor },
{ offset: topPercent, color: chartToken.errorColor },
{ offset: topPercent + 0.0001, color: originColor },
{ offset: 1, color: originColor }
]
return colorStops
}
function handleColorStopsOther(originColor, topPercent, bottomPercent) {
const colorStops = [
{ offset: 0, color: chartToken.errorColor },
{ offset: topPercent, color: chartToken.errorColor },
{ offset: topPercent + 0.0001, color: originColor },
{ offset: bottomPercent, color: originColor },
{ offset: bottomPercent + 0.0001, color: chartToken.errorColor },
{ offset: 1, color: chartToken.errorColor }
]
return colorStops
}
function handleResObj(d, direction, colorStops) {
const resObj = {
value: d,
itemStyle: {
color: {
type: 'linear',
x: direction === 'horizontal' ? 1 : 0,
y: direction === 'horizontal' ? 0 : 0,
x2: direction === 'horizontal' ? 0 : 0,
y2: direction === 'horizontal' ? 0 : 1,
colorStops
}
}
}
return resObj
}
function handleSeries(iChartOption, baseOption, exclude, colors, direction) {
// 顶部阈值
let top = iChartOption.markLine.top
// 底部阈值
let bottom = iChartOption.markLine.bottom
const usefullSeries = baseOption.series.filter((item) => {
return !exclude.includes(item.name)
})
usefullSeries.forEach((item, index) => {
if (!exclude.includes(item.name)) {
const barData = item.data
const placeHolderData = baseOption.series[index * 2].data
item.data = barData.map((d, i) => {
const pd = placeHolderData[i]
if (top === undefined) {
top = pd + d + 1
}
if (bottom === undefined) {
bottom = pd - 1
}
const originColor = getColor(colors, index)
let topPercent = 0
let bottomPercent = 1
topPercent = (d + pd - top) / d
topPercent < 0 && (topPercent = 0)
topPercent > 1 && (topPercent = 1)
bottomPercent = (d + pd - bottom) / d
bottomPercent < 0 && (bottomPercent = 0)
bottomPercent > 1 && (bottomPercent = 1)
let colorStops = []
if (topPercent === 1 || bottomPercent === 0) {
// 纯红
colorStops = colorStopsOrigin
} else if (topPercent === 0 && bottomPercent === 1) {
// 原色
return d
} else if (topPercent === 0) {
colorStops = handleColorStopsTop(originColor, bottomPercent)
} else if (bottomPercent === 1) {
colorStops = handleColorStopsBottom(originColor, topPercent)
} else {
colorStops = handleColorStopsOther(originColor, topPercent, bottomPercent)
}
const resObj = handleResObj(d, direction, colorStops)
return resObj
})
}
})
}
// 针对阈值线以上显示红色区域的需求,图表需要进行特殊处理
export function setMarkLine(baseOption, iChartOption) {
const type = iChartOption.type
const colors = baseOption.color
const direction = iChartOption.direction
const exclude = ['Placeholder']
if (iChartOption.markLine && type !== 'water-fall' && type !== 'range') {
// 顶部阈值
const top = iChartOption.markLine.top
const topUse = iChartOption.markLine.topUse
// 底部阈值
const bottom = iChartOption.markLine.bottom
const bottomUse = iChartOption.markLine.bottomUse
// 用户自定义阈值线颜色
const markLineColor = iChartOption.markLine.color
const usefullSeries = baseOption.series.filter((item) => {
return !exclude.includes(item.name)
})
usefullSeries.forEach((item, index) => {
if (!exclude.includes(item.name)) {
const barData = item.data
item.data = barData.map((d) => {
const originColor = getColor(colors, index)
// 如果该柱形高度超过阈值,侧改变其颜色
if (top && d >= 0 && top >= 0 && d > top) {
if (topUse && !topUse.includes(item.name)) {
return d
}
const percent = (d - top) / (d - 0)
const topObj = handleTopObj(d, direction, percent, originColor, markLineColor)
return topObj
// 如果该柱形高度低于阈值,侧改变其颜色
} else if (bottom && d <= 0 && bottom <= 0 && d < bottom) {
if (bottomUse && !bottomUse.includes(item.name)) {
return d
}
const percent = (bottom - d) / (0 - d)
const bottomObj = handleBottomObj(d, direction, percent, originColor, markLineColor)
return bottomObj
} else {
return d
}
})
}
})
}
//
if (iChartOption.markLine && type === 'range') {
handleSeries(iChartOption, baseOption, exclude, colors, direction)
}
}
function placeFun(index, placeholderData) {
const a = {
name: 'Placeholder',
type: 'bar',
stack: `stack${index}`,
itemStyle: {
borderColor: chartToken.borderColor,
color: chartToken.color
},
emphasis: {
itemStyle: {
borderColor: chartToken.borderColor,
color: chartToken.color
}
},
data: placeholderData
}
return a
}
// 针对区间图表需求,图表需要进行特殊处理
export function setRange(baseOption, iChartOption) {
const type = iChartOption.type
if (type && type === 'range') {
const tempArray = []
baseOption.series.forEach((item, index) => {
const barData = item.data
const barRealData = []
const placeholderData = []
const placeholder = placeFun(index, placeholderData)
barData.forEach((d) => {
placeholderData.push(d[0])
barRealData.push(d[1] - d[0])
})
item.stack = `stack${index}`
item.data = barRealData
tempArray.push(placeholder)
tempArray.push(item)
})
baseOption.series = tempArray
}
}
// 针对瀑布图表需求,图表需要进行特殊处理
export function setWaterFall(baseOption, iChartOption) {
const type = iChartOption.type
const totalName = iChartOption.totalName || 'Total'
const totalPosition = iChartOption.totalPosition || 'end'
if (type && type === 'water-fall') {
const tempArray = []
baseOption.series.forEach((item, index) => {
const barData = item.data
const placeholderData = [0]
const placeholder = placeFun(index, placeholderData)
if (totalPosition === 'end') {
barData.forEach((d, i) => {
if (i < barData.length - 1) {
placeholderData.push((Number(d) || 0) + placeholderData[i])
}
})
placeholderData[placeholderData.length - 1] = 0
} else {
barData.unshift(barData.pop())
placeholderData[0] = barData[0]
barData.forEach((d, i) => {
if (i > 0) {
placeholderData.push(placeholderData[i - 1] - (Number(d) || 0))
}
})
placeholderData[0] = 0
}
item.stack = `stack${index}`
tempArray.push(placeholder)
tempArray.push(item)
})
if (totalPosition === 'end') {
baseOption.xAxis[0].data.push(totalName)
} else {
baseOption.xAxis[0].data.unshift(totalName)
}
baseOption.series = tempArray
}
}
/**
* seriesPlaceHolder series
* tooltip series
* tooltip.formatter
*/
export function setLimitFormatter(baseOption, iChartOption) {
const type = iChartOption.type
const toolTipFormatter = baseOption.tooltip.formatter
const exclude = ['Placeholder']
const colors = baseOption.color
baseOption.tooltip.formatter = (params, ticket, callback) => {
const newParams = params.filter((item) => {
return !exclude.includes(item.seriesName)
})
if (toolTipFormatter) {
return toolTipFormatter(newParams, ticket, callback)
}
let htmlString = ''
newParams.forEach((item, index) => {
if (index === 0) {
htmlString += `<div style="margin-bottom:4px;">${defendXSS(item.name)}</div>`
}
const itemColor = typeof item.color === 'string' ? item.color : getColor(colors, index)
htmlString += `
<div>
<span style="display:inline-block;width:10px;height:10px;border-radius:5px;background-color:${defendXSS(
itemColor
)};">
</span>
<span style="margin-left:5px;">
<span style="display:inline-block;margin-right:8px;min-width:60px;">${defendXSS(
item.seriesName
)}</span>
<span style="font-weight:bold">
${defendXSS(
type === 'range'
? `${`${`[${params[index * 2].value}`}-${params[index * 2].value + item.value}`}]`
: item.value
)}
</span>
</span>
</div>
`
})
return htmlString
}
}
function handleYaxis(series, yAxis) {
if (Array.isArray(yAxis)) {
yAxis.forEach((y, index) => {
series.forEach((s, indexs) => {
if (y.dataName && y.dataName.includes(s.name)) {
series[indexs].yAxisIndex = index
}
})
})
}
}

View File

@ -0,0 +1,37 @@
import min from '../../util/sort/min'
import max from '../../util/sort/max'
import { getColor } from '../../util/color'
import chartToken from './chartToken'
export function setVisualMap(legendData, seriesData, markLine, colors) {
const visualMap = []
if (markLine) {
const topValue = markLine.top
const bottomValue = markLine.bottom
legendData.forEach((legendName, index) => {
const data = seriesData[legendName]
const minData = min(data)
const maxData = max(data)
const bottom = bottomValue || minData - 1
const top = topValue || maxData + 1
// 根据数据大小映射颜色
visualMap.push({
show: false,
type: 'piecewise',
dimension: 1,
seriesIndex: index,
pieces: [
{
gt: bottom,
lt: top,
color: getColor(colors, index)
}
],
outOfRange: {
color: chartToken.errorColor
}
})
})
}
return visualMap
}

View File

@ -0,0 +1,112 @@
import LineChart from '../LineChart'
import init from '../../option/init'
import { event } from '../../util/event'
import cloneDeep from '../../util/cloneDeep'
import BaseOption from '../../util/baseOption'
import { mergeVisualMap, mergeSeries } from '../../util/merge'
import RectCoordSys from '../../option/RectSys'
import { setStack, setDirection, setDoubleSides } from './handleOptipn'
import { xkey, xdata, ldata, ydata } from '../../option/RectSys'
import { setSeries, setRange, setMarkLine, setWaterFall, setLimitFormatter } from './handleSeries'
class BarChart {
constructor(iChartOption, chartInstance) {
this.baseOption = {}
this.baseOption = cloneDeep(BaseOption)
this.chartInstance = chartInstance
// 组装 iChartOption, 补全默认值
this.iChartOption = init(iChartOption)
// 根据 iChartOption 组装 baseOption
this.updateOption()
}
updateOption() {
const theme = this.iChartOption.theme
const iChartOption = this.iChartOption
// 装载除series之外的其他配置
RectCoordSys(this.baseOption, this.iChartOption, 'BarChart')
// x轴key值
const xAxisKey = xkey(iChartOption)
// x轴数据
const xAxisData = xdata(iChartOption.data, xAxisKey)
// 图例数据
const legendData = ldata(iChartOption.data, xAxisKey)
// 连线的数据
const seriesData = ydata(iChartOption.data, legendData)
// 赋值数据
this.baseOption.legend.data = iChartOption.legend.data || legendData
this.baseOption.xAxis.forEach((item) => {
item.data = xAxisData
})
this.baseOption.series = setSeries(seriesData, legendData, iChartOption)
// 给堆叠图的柱子中间加上空白缝隙,并覆盖图例的点击事件
setStack(this.baseOption, iChartOption, legendData, seriesData)
// 针对数据均为正数的双向柱状图进行一些特殊处理
setDoubleSides(this.baseOption, iChartOption)
// 针对瀑布图表需求,图表需要进行特殊处理
setWaterFall(this.baseOption, iChartOption)
// 针对区间图表需求,图表需要进行特殊处理
setRange(this.baseOption, iChartOption)
// 针对阈值线变色,图表需要进行特殊处理
setMarkLine(this.baseOption, iChartOption)
// 设置柱状图的方向
setDirection(this.baseOption, iChartOption.direction)
// 对 tooltip.formatter 进行二次封装
setLimitFormatter(this.baseOption, iChartOption)
// 配置图表事件
if (iChartOption.event) {
event(this.chartInstance, iChartOption.event)
}
// 是否关闭hover态的效果默认为false
if (iChartOption.silent) {
this.baseOption.tooltip = {}
}
// 合并用户自定义series
mergeSeries(iChartOption, this.baseOption)
// 合并用户自定义visualMap
mergeVisualMap(iChartOption, this.baseOption)
console.log({ ...this.baseOption }, '==-====')
}
// 根据渲染出的结果二次计算option
updateOptionAgain(YAxiMax, YAxiMin) {
const baseOption = this.baseOption
const iChartOption = this.iChartOption
const lineDataName = iChartOption.lineDataName
// 折柱混合
if (lineDataName && lineDataName.length > 0) {
const lineChartBaseOpt = new LineChart(iChartOption, {}, this.chartInstance)
const lineBaseOption = lineChartBaseOpt.getOption()
const lineSeries = lineBaseOption.series
const barSeries = baseOption.series
lineDataName.forEach((lineName) => {
let bar = null
let line = null
for (let i = 0; i < lineSeries.length; i++) {
if (lineSeries[i].name === lineName) {
line = lineSeries[i]
break
}
}
for (let i = 0; i < barSeries.length; i++) {
if (barSeries[i].name === lineName) {
bar = barSeries[i]
break
}
}
for (const key in line) {
bar[key] = line[key]
}
})
}
}
getOption() {
return this.baseOption
}
setOption() {}
}
export default BarChart

View File

@ -0,0 +1,113 @@
import { insertStateDom, removeStateDom } from '../../util/init/insert'
export default class BaseChart {
// 图表渲染容器
dom
// 图表渲染配置
option
constructor() {
// 必须实现 init 方法,初始化图表渲染容器
if (this.init === undefined) {
throw new Error('This chart has not overwrite "init" callback!')
}
// 必须实现 setSimpleOption 方法,初始化图表渲染配置
if (this.setSimpleOption === undefined) {
throw new Error('This chart has not overwrite "setSimpleOption" callback!')
}
// 必须实现 render 方法,调用时开始渲染图表
if (this.render === undefined) {
throw new Error('This chart has not overwrite "render" callback!')
}
// 必须实现 onRenderReady 方法
if (this.onRenderReady === undefined) {
throw new Error('This chart has not overwrite "onRenderReady" callback!')
}
// 必须实现 refresh 方法传入新的option刷新图表
if (this.refresh === undefined) {
throw new Error('This chart has not overwrite "refresh" callback!')
}
// 必须实现 refreshData 方法传入新的data刷新图表
if (this.refreshData === undefined) {
throw new Error('This chart has not overwrite "refreshData" callback!')
}
// 必须实现 setResize 方法,该方法一般手动调用,实现图表自适应宽度
if (this.setResize === undefined) {
throw new Error('This chart has not overwrite "setResize" callback!')
}
// 必须实现 uninstall 方法,清空图表容器,卸载所有监听事件
if (this.uninstall === undefined) {
throw new Error('This chart has not overwrite "uninstall" callback!')
}
}
// 加载状态
showLoading(option) {
insertStateDom(this.dom, 'loading', option)
}
hideLoading() {
removeStateDom(this.dom, 'loading')
}
closeLoading() {
removeStateDom(this.dom, 'loading')
}
// 错误状态
showError(option) {
insertStateDom(this.dom, 'error', option)
}
closeError() {
removeStateDom(this.dom, 'error')
}
// 空数据状态
showEmpty(option) {
insertStateDom(this.dom, 'empty', option)
}
closeEmpty() {
removeStateDom(this.dom, 'empty')
}
// 阶段空数据状态
showStageEmpty(option) {
insertStateDom(this.dom, 'stage_empty', option)
}
closeStageEmpty() {
removeStateDom(this.dom, 'stage_empty')
}
// 自定义数据状态
showState(option) {
insertStateDom(this.dom, 'custom', option)
}
closeState() {
removeStateDom(this.dom, 'custom')
}
// 传入自定义DOM
showCustomDom(callback) {
if (this.dom.getElementsByClassName('huicharts-custom-dom').length > 0) return
if (getComputedStyle(this.dom).position == ('static' || '')) {
this.dom.style.position = 'relative'
}
let customContainer = document.createElement('div')
customContainer.className = 'huicharts-custom-dom'
customContainer.setAttribute(
'style',
'position:absolute;width:100%;height:100%;top:0px;left:0px;display:flex;justify-content:center;align-items:center'
)
this.dom.appendChild(customContainer)
callback(customContainer)
}
// 删除自定义DOM
closeCustomDom() {
let customContainer = this.dom.getElementsByClassName('huicharts-custom-dom')
this.dom.removeChild(customContainer[0])
}
}

Some files were not shown because too many files have changed in this diff Show More