1/*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16const DEFAULT_BAR_WIDTH: number = 96;
17const DEFAULT_BAR_HEIGHT: number = 52;
18
19@Component
20export struct AtomicServiceTabs {
21  @BuilderParam tabContents?: [TabContentBuilder?,
22                              TabContentBuilder?,
23                              TabContentBuilder?,
24                              TabContentBuilder?,
25                              TabContentBuilder?];
26  @Prop tabBarOptionsArray: [TabBarOptions, TabBarOptions, TabBarOptions?, TabBarOptions?, TabBarOptions?];
27  @Prop tabBarPosition?: TabBarPosition = TabBarPosition.BOTTOM;
28  @Prop barBackgroundColor?: ResourceColor = Color.Transparent;
29  @Prop index?: number | undefined = 0;
30  @Prop barOverlap?: boolean = true;
31  controller?: TabsController = new TabsController();
32  onChange?: Callback<number>;
33  onTabBarClick?: Callback<number>;
34  onContentWillChange?: OnContentWillChangeCallback;
35
36  build() {
37    Tabs({
38      barPosition: this.tabBarPosition === TabBarPosition.LEFT ? BarPosition.Start : BarPosition.End,
39      index: this.index,
40      controller: this.controller
41    }) {
42      ForEach(this.tabBarOptionsArray, (item: TabBarOptions, index: number) => {
43        if (item) {
44          TabContent() {
45            if (this.tabContents && this.tabContents[index]) {
46              this.tabContents[index]?.()
47            }
48          }
49          .tabBar(BottomTabBarStyle.of(item.icon, item.text)
50            .labelStyle({ unselectedColor: item.unselectedColor, selectedColor: item.selectedColor })
51            .iconStyle({ unselectedColor: item.unselectedColor, selectedColor: item.selectedColor }))
52          .width((!this.tabContents && this.tabBarPosition === TabBarPosition.LEFT) ? DEFAULT_BAR_WIDTH : '100%')
53          .height((!this.tabContents && this.tabBarPosition === TabBarPosition.BOTTOM) ? DEFAULT_BAR_HEIGHT : '100%')
54        }
55      })
56    }
57    .barBackgroundColor(this.barBackgroundColor)
58    .divider(null)
59    .vertical(this.tabBarPosition === TabBarPosition.LEFT ? true : false)
60    .scrollable(false)
61    .barOverlap(this.barOverlap)
62    .barBackgroundBlurStyle(BlurStyle.COMPONENT_THICK)
63    .onChange(this.onChange)
64    .onTabBarClick(this.onTabBarClick)
65    .onContentWillChange(this.onContentWillChange)
66    .width((!this.tabContents && this.tabBarPosition === TabBarPosition.LEFT) ? DEFAULT_BAR_WIDTH : '100%')
67    .height((!this.tabContents && this.tabBarPosition === TabBarPosition.BOTTOM) ? DEFAULT_BAR_HEIGHT : '100%')
68  }
69}
70
71export class TabBarOptions {
72  public icon: ResourceStr | TabBarSymbol;
73  public text: ResourceStr;
74  public unselectedColor?: ResourceColor;
75  public selectedColor?: ResourceColor;
76
77  constructor(icon: ResourceStr | TabBarSymbol, text: ResourceStr,
78              unselectedColor?: ResourceColor, selectedColor?: ResourceColor) {
79    this.icon = icon;
80    this.text = text;
81    this.unselectedColor = unselectedColor;
82    this.selectedColor = selectedColor;
83  }
84}
85
86export enum TabBarPosition {
87  LEFT = 0,
88  BOTTOM = 1
89}
90
91export type TabContentBuilder = () => void;
92export type OnContentWillChangeCallback = (currentIndex: number, comingIndex: number) => boolean;