@didaoktv/didaoui-uniapp 1.3.8 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,208 @@
1
+ <template>
2
+ <view class="dd-tree-select" :style="rootStyle">
3
+ <!-- 左侧分类导航(dd-sidebar) -->
4
+ <scroll-view class="dd-tree-select__nav" :scroll-y="true">
5
+ <dd-sidebar :model-value="mainActiveIndex" @update:model-value="onNavChange">
6
+ <dd-sidebar-item
7
+ v-for="(item, index) in items"
8
+ :key="index"
9
+ :title="item.text"
10
+ :dot="item.dot"
11
+ :badge="item.badge"
12
+ :disabled="item.disabled"
13
+ :custom-class="item.className"
14
+ >
15
+ <template #title>
16
+ <slot name="nav-text" :item="item">{{ item.text }}</slot>
17
+ </template>
18
+ </dd-sidebar-item>
19
+ </dd-sidebar>
20
+ </scroll-view>
21
+ <!-- 右侧子项区(content 插槽可整体自定义) -->
22
+ <scroll-view class="dd-tree-select__content" :scroll-y="true">
23
+ <slot name="content">
24
+ <view
25
+ v-for="child in activeChildren"
26
+ :key="child.id"
27
+ class="dd-tree-select__item"
28
+ :class="{
29
+ 'dd-tree-select__item--active': isActive(child.id),
30
+ 'dd-tree-select__item--disabled': child.disabled,
31
+ }"
32
+ @click="onItemClick(child)"
33
+ >
34
+ <text class="dd-tree-select__item-text">{{ child.text }}</text>
35
+ <dd-icon
36
+ v-if="isActive(child.id)"
37
+ :name="selectedIcon"
38
+ class="dd-tree-select__selected"
39
+ />
40
+ </view>
41
+ </slot>
42
+ </scroll-view>
43
+ </view>
44
+ </template>
45
+
46
+ <script setup lang="ts">
47
+ import { computed } from 'vue'
48
+ import DdIcon from '../dd-icon/dd-icon.vue'
49
+ import DdSidebar from '../dd-sidebar/dd-sidebar.vue'
50
+ import DdSidebarItem from '../dd-sidebar-item/dd-sidebar-item.vue'
51
+
52
+ /** 右侧子选项 */
53
+ interface TreeSelectChild {
54
+ /** 选项唯一 id */
55
+ id: string | number
56
+ /** 选项文案 */
57
+ text: string
58
+ disabled?: boolean
59
+ }
60
+
61
+ /** 左侧导航分类项 */
62
+ interface TreeSelectItem {
63
+ /** 导航文案 */
64
+ text?: string
65
+ disabled?: boolean
66
+ /** 导航项右上角红点 */
67
+ dot?: boolean
68
+ /** 导航项右上角徽标数 */
69
+ badge?: string | number
70
+ /** 额外类名 */
71
+ className?: string
72
+ /** 该分类下的子选项 */
73
+ children?: TreeSelectChild[]
74
+ }
75
+
76
+ interface Props {
77
+ /** 分类数据(左侧导航 + 右侧子项) */
78
+ items?: TreeSelectItem[]
79
+ /** 左侧导航选中索引(v-model:main-active-index) */
80
+ mainActiveIndex?: number
81
+ /** 右侧选中项 id,传数组开启多选(v-model:active-id) */
82
+ activeId?: string | number | Array<string | number>
83
+ /** 多选时最多可选数量(activeId 为数组时生效) */
84
+ max?: number
85
+ /** 组件高度,数字按 px,字符串原样输出(支持 rpx) */
86
+ height?: string | number
87
+ /** 选中项右侧图标名(dd-icon name) */
88
+ selectedIcon?: string
89
+ }
90
+
91
+ const props = withDefaults(defineProps<Props>(), {
92
+ items: () => [],
93
+ mainActiveIndex: 0,
94
+ activeId: 0,
95
+ max: Number.POSITIVE_INFINITY,
96
+ height: 300,
97
+ selectedIcon: 'success',
98
+ })
99
+
100
+ const emit = defineEmits<{
101
+ (e: 'update:mainActiveIndex', index: number): void
102
+ (e: 'update:activeId', id: string | number | Array<string | number>): void
103
+ (e: 'clickNav', index: number): void
104
+ (e: 'clickItem', item: TreeSelectChild): void
105
+ }>()
106
+
107
+ const rootStyle = computed(() => ({
108
+ height: typeof props.height === 'number' ? `${props.height}px` : props.height,
109
+ }))
110
+
111
+ /** 当前选中分类的子选项 */
112
+ const activeChildren = computed<TreeSelectChild[]>(
113
+ () => props.items[props.mainActiveIndex]?.children ?? [],
114
+ )
115
+
116
+ function isActive(id: string | number) {
117
+ return Array.isArray(props.activeId) ? props.activeId.includes(id) : props.activeId === id
118
+ }
119
+
120
+ function onNavChange(index: number) {
121
+ emit('update:mainActiveIndex', index)
122
+ emit('clickNav', index)
123
+ }
124
+
125
+ function onItemClick(child: TreeSelectChild) {
126
+ if (child.disabled) return
127
+ let activeId: string | number | Array<string | number>
128
+ if (Array.isArray(props.activeId)) {
129
+ activeId = props.activeId.slice()
130
+ const index = activeId.indexOf(child.id)
131
+ if (index !== -1) {
132
+ activeId.splice(index, 1)
133
+ } else if (activeId.length < props.max) {
134
+ activeId.push(child.id)
135
+ } else {
136
+ return
137
+ }
138
+ } else {
139
+ activeId = child.id
140
+ }
141
+ emit('update:activeId', activeId)
142
+ emit('clickItem', child)
143
+ }
144
+ </script>
145
+
146
+ <style lang="scss" scoped>
147
+ @import '../../scss/variables';
148
+ @import '../../scss/mixins';
149
+
150
+ .dd-tree-select {
151
+ display: flex;
152
+ font-size: $dd-font-size-body;
153
+
154
+ &__nav {
155
+ flex: 1;
156
+ height: 100%;
157
+ background: var(--dd-bg-section, #{$dd-bg-section});
158
+ }
159
+
160
+ &__content {
161
+ flex: 2;
162
+ height: 100%;
163
+ background: var(--dd-bg-card, #{$dd-bg-card});
164
+ }
165
+
166
+ &__item {
167
+ position: relative;
168
+ display: flex;
169
+ align-items: center;
170
+ justify-content: space-between;
171
+ min-height: 96rpx;
172
+ padding: 0 88rpx 0 $dd-space-4;
173
+ font-weight: 600;
174
+ color: var(--dd-text-primary, #{$dd-text-primary});
175
+
176
+ &:active {
177
+ background: var(--dd-interactive-hover, #{$dd-interactive-hover});
178
+ }
179
+
180
+ &--active {
181
+ color: var(--dd-primary, #{$dd-primary});
182
+ }
183
+
184
+ &--disabled {
185
+ color: var(--dd-text-tertiary, #{$dd-text-tertiary});
186
+
187
+ &:active {
188
+ background: transparent;
189
+ }
190
+ }
191
+ }
192
+
193
+ &__item-text {
194
+ overflow: hidden;
195
+ white-space: nowrap;
196
+ text-overflow: ellipsis;
197
+ }
198
+
199
+ &__selected {
200
+ position: absolute;
201
+ top: 50%;
202
+ right: $dd-space-4;
203
+ transform: translateY(-50%);
204
+ font-size: 32rpx;
205
+ color: var(--dd-primary, #{$dd-primary});
206
+ }
207
+ }
208
+ </style>
package/index.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { App } from 'vue'
2
2
 
3
- // === Input (23) ===
3
+ // === Input (24) ===
4
4
  import DdButton from './components/dd-button/dd-button.vue'
5
5
  import DdCodeButton from './components/dd-code-button/dd-code-button.vue'
6
6
  import DdInput from './components/dd-input/dd-input.vue'
@@ -24,8 +24,9 @@ import DdNumberKeyboard from './components/dd-number-keyboard/dd-number-keyboard
24
24
  import DdCarKeyboard from './components/dd-car-keyboard/dd-car-keyboard.vue'
25
25
  import DdCascader from './components/dd-cascader/dd-cascader.vue'
26
26
  import DdGoodsSku from './components/dd-goods-sku/dd-goods-sku.vue'
27
+ import DdTreeSelect from './components/dd-tree-select/dd-tree-select.vue'
27
28
 
28
- // === Navigation (12) ===
29
+ // === Navigation (14) ===
29
30
  import DdNavigation from './components/dd-navigation/dd-navigation.vue'
30
31
  import DdTopNavbar from './components/dd-top-navbar/dd-top-navbar.vue'
31
32
  import DdSegmentedTab from './components/dd-segmented-tab/dd-segmented-tab.vue'
@@ -38,8 +39,10 @@ import DdCollapse from './components/dd-collapse/dd-collapse.vue'
38
39
  import DdCollapseItem from './components/dd-collapse-item/dd-collapse-item.vue'
39
40
  import DdDropdownMenu from './components/dd-dropdown-menu/dd-dropdown-menu.vue'
40
41
  import DdDropdownItem from './components/dd-dropdown-item/dd-dropdown-item.vue'
42
+ import DdSidebar from './components/dd-sidebar/dd-sidebar.vue'
43
+ import DdSidebarItem from './components/dd-sidebar-item/dd-sidebar-item.vue'
41
44
 
42
- // === Layout (8) ===
45
+ // === Layout (9) ===
43
46
  import DdCard from './components/dd-card/dd-card.vue'
44
47
  import DdRoomCard from './components/dd-room-card/dd-room-card.vue'
45
48
  import DdFeatureGrid from './components/dd-feature-grid/dd-feature-grid.vue'
@@ -48,8 +51,9 @@ import DdBillDetail from './components/dd-bill-detail/dd-bill-detail.vue'
48
51
  import DdWorkorderCard from './components/dd-workorder-card/dd-workorder-card.vue'
49
52
  import DdCalendar from './components/dd-calendar/dd-calendar.vue'
50
53
  import DdQrcode from './components/dd-qrcode/dd-qrcode.vue'
54
+ import DdSubmitBar from './components/dd-submit-bar/dd-submit-bar.vue'
51
55
 
52
- // === Display (24) ===
56
+ // === Display (25) ===
53
57
  import DdTag from './components/dd-tag/dd-tag.vue'
54
58
  import DdStatCard from './components/dd-stat-card/dd-stat-card.vue'
55
59
  import DdChampionCard from './components/dd-champion-card/dd-champion-card.vue'
@@ -74,6 +78,7 @@ import DdAlbum from './components/dd-album/dd-album.vue'
74
78
  import DdCoupon from './components/dd-coupon/dd-coupon.vue'
75
79
  import DdParse from './components/dd-parse/dd-parse.vue'
76
80
  import DdMarkdown from './components/dd-markdown/dd-markdown.vue'
81
+ import DdPrice from './components/dd-price/dd-price.vue'
77
82
 
78
83
  // === Overlay (11) ===
79
84
  import DdPortal from './components/dd-portal/dd-portal.vue'
@@ -110,15 +115,17 @@ const components = {
110
115
  DdButton, DdCodeButton, DdInput, DdSwitch, DdCheckbox, DdCheckboxGroup, DdRadio, DdRadioGroup, DdForm,
111
116
  DdSearchBar, DdSlider, DdStepper, DdDatePicker, DdField,
112
117
  DdPicker, DdRate, DdUpload, DdIcon,
113
- DdKeyboard, DdNumberKeyboard, DdCarKeyboard, DdCascader, DdGoodsSku,
118
+ DdKeyboard, DdNumberKeyboard, DdCarKeyboard, DdCascader, DdGoodsSku, DdTreeSelect,
114
119
  DdNavigation, DdTopNavbar, DdSegmentedTab, DdSwipeableTab,
115
120
  DdDrawer, DdTabbar, DdTabbarItem, DdBacktop,
116
121
  DdCollapse, DdCollapseItem, DdDropdownMenu, DdDropdownItem,
122
+ DdSidebar, DdSidebarItem,
117
123
  DdCard, DdRoomCard, DdFeatureGrid, DdSticky, DdBillDetail, DdWorkorderCard, DdCalendar, DdQrcode,
124
+ DdSubmitBar,
118
125
  DdTag, DdStatCard, DdChampionCard, DdAvatar, DdAvatarGroup, DdBadge,
119
126
  DdListCell, DdCell, DdCellGroup, DdCountDown, DdDivider,
120
127
  DdImage, DdProgress, DdSkeleton, DdEmptyState, DdStep, DdSteps,
121
- DdText, DdLink, DdCopy, DdAlbum, DdCoupon, DdParse, DdMarkdown,
128
+ DdText, DdLink, DdCopy, DdAlbum, DdCoupon, DdParse, DdMarkdown, DdPrice,
122
129
  DdModal, DdActionSheet, DdToast, DdAlert, DdLoading,
123
130
  DdPortal, DdDialog, DdOverlay, DdPopup, DdPopover, DdPopoverItem,
124
131
  DdSwipeAction, DdSwipe, DdSwipeItem, DdPullRefresh, DdLoadmore,
@@ -140,15 +147,17 @@ export {
140
147
  DdButton, DdCodeButton, DdInput, DdSwitch, DdCheckbox, DdCheckboxGroup, DdRadio, DdRadioGroup, DdForm,
141
148
  DdSearchBar, DdSlider, DdStepper, DdDatePicker, DdField,
142
149
  DdPicker, DdRate, DdUpload, DdIcon,
143
- DdKeyboard, DdNumberKeyboard, DdCarKeyboard, DdCascader, DdGoodsSku,
150
+ DdKeyboard, DdNumberKeyboard, DdCarKeyboard, DdCascader, DdGoodsSku, DdTreeSelect,
144
151
  DdNavigation, DdTopNavbar, DdSegmentedTab, DdSwipeableTab,
145
152
  DdDrawer, DdTabbar, DdTabbarItem, DdBacktop,
146
153
  DdCollapse, DdCollapseItem, DdDropdownMenu, DdDropdownItem,
154
+ DdSidebar, DdSidebarItem,
147
155
  DdCard, DdRoomCard, DdFeatureGrid, DdSticky, DdBillDetail, DdWorkorderCard, DdCalendar, DdQrcode,
156
+ DdSubmitBar,
148
157
  DdTag, DdStatCard, DdChampionCard, DdAvatar, DdAvatarGroup, DdBadge,
149
158
  DdListCell, DdCell, DdCellGroup, DdCountDown, DdDivider,
150
159
  DdImage, DdProgress, DdSkeleton, DdEmptyState, DdStep, DdSteps,
151
- DdText, DdLink, DdCopy, DdAlbum, DdCoupon, DdParse, DdMarkdown,
160
+ DdText, DdLink, DdCopy, DdAlbum, DdCoupon, DdParse, DdMarkdown, DdPrice,
152
161
  DdModal, DdActionSheet, DdToast, DdAlert, DdLoading,
153
162
  DdPortal, DdDialog, DdOverlay, DdPopup, DdPopover, DdPopoverItem,
154
163
  DdSwipeAction, DdSwipe, DdSwipeItem, DdPullRefresh, DdLoadmore,
@@ -167,4 +176,4 @@ export type {
167
176
  } from './components/dd-form/rules'
168
177
 
169
178
  // 图标元数据(供 demo/文档消费,与 dd-icon.vue 内 SCSS &-- 规则保持一致)
170
- export { iconNames, iconGroups } from './components/dd-icon/dd-icon.vue'
179
+ export { iconNames, iconGroups, iconLabels } from './components/dd-icon/dd-icon.vue'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@didaoktv/didaoui-uniapp",
3
- "version": "1.3.8",
3
+ "version": "1.4.0",
4
4
  "description": "帝到KTV UniApp 组件库",
5
5
  "main": "index.ts",
6
6
  "types": "index.ts",
@@ -102,6 +102,7 @@ $dd-theme-dark: (
102
102
  'bg-section': $dd-bg-section,
103
103
  'bg-card': $dd-bg-card,
104
104
  'bg-elevated': $dd-bg-elevated,
105
+ 'bg-popup': $dd-bg-popup,
105
106
  'text-primary': $dd-text-primary,
106
107
  'text-secondary': $dd-text-secondary,
107
108
  'text-tertiary': $dd-text-tertiary,
@@ -150,6 +151,7 @@ $dd-theme-light: (
150
151
  'bg-section': $dd-light-bg-section,
151
152
  'bg-card': $dd-light-bg-card,
152
153
  'bg-elevated': $dd-light-bg-elevated,
154
+ 'bg-popup': $dd-light-bg-popup,
153
155
  'text-primary': $dd-light-text-primary,
154
156
  'text-secondary': $dd-light-text-secondary,
155
157
  'text-tertiary': $dd-light-text-tertiary,
@@ -119,6 +119,8 @@ $dd-surface-container-highest: $dd-neutral-600 !default;
119
119
  $dd-bg-section: $dd-neutral-800 !default;
120
120
  $dd-bg-card: $dd-neutral-800 !default;
121
121
  $dd-bg-elevated: $dd-neutral-800 !default;
122
+ // 弹出层专用底色:比卡片(neutral-800)亮一档,形成 页面→卡片→弹出层 的抬升层级
123
+ $dd-bg-popup: #222222 !default;
122
124
 
123
125
  // === 文本色 ===
124
126
  $dd-text-primary: $dd-neutral-50 !default;
@@ -168,6 +170,7 @@ $dd-light-surface-container-highest: $dd-neutral-100 !default;
168
170
  $dd-light-bg-section: $dd-neutral-50 !default;
169
171
  $dd-light-bg-card: #FFFFFF !default;
170
172
  $dd-light-bg-elevated: #FFFFFF !default; // ★推导(同 bg-card)
173
+ $dd-light-bg-popup: #FFFFFF !default; // ★推导(浅色下靠阴影区分,弹出层同卡片白)
171
174
  $dd-light-text-primary: $dd-neutral-900 !default;
172
175
  $dd-light-text-secondary: $dd-neutral-700 !default; // ★推导
173
176
  $dd-light-text-tertiary: $dd-neutral-500 !default; // ★推导