添加Chip 组件示例

Signed-off-by: youzhi92 <chenyouzhi@huawei.com>
This commit is contained in:
youzhi92 2024-07-11 17:47:58 +08:00
parent 0801a53f31
commit b54bac83ca
11 changed files with 410 additions and 16 deletions

View File

@ -13,6 +13,6 @@
* limitations under the License.
*/
export * from './src/main/ets/components/ColorBlock';
export * from './src/main/ets/components/RadioBlock';
export * from './src/main/ets/components/SliderBlock';
export * from './src/main/ets/components';
export * from './src/main/ets/utils';

View File

@ -16,7 +16,8 @@
@Component
export struct ColorPalette {
@Prop color: ResourceColor | undefined = undefined;
@Prop colors: ResourceColor[] = ['#0A59F7', '#646AFD', '#FE7062', '#E9E8ED', '#1C1C1C'];
@Prop colors: ResourceColor[] =
['#0A59F7', '#646AFD', '#FE7062', '#E9E8ED', '#1C1C1C', $r('sys.color.ohos_id_color_text_primary_contrary')];
@Prop isEnabled: boolean = false;
onChange?: (color: ResourceColor) => void;
@ -49,6 +50,7 @@ export struct ColorPalette {
})
})
}
.enabled(this.isEnabled)
.width('100%')
.grayscale(this.isEnabled ? 0 : 1)
}

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Block } from './Block';
import { IconPalette } from './IconPalette';
@Component
export struct IconBlock {
@Prop title: string;
@Link isEnabled: boolean;
@Link icon: ResourceStr;
build() {
Block({
title: this.title,
isEnabled: $isEnabled
}) {
IconPalette({
icon: this.icon,
onChange: (icon) => {
this.icon = icon
},
isEnabled: this.isEnabled
})
}
}
}
@Preview
@Component
struct IconBlockPreview {
@State isEnabled: boolean = true
@State icon: ResourceStr = '#fd5d77'
build() {
IconBlock({
title: '标题',
isEnabled: $isEnabled,
icon: $icon
})
}
}

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@Component
export struct IconPalette {
@Prop icon: ResourceStr | undefined = undefined;
@Prop icons: ResourceStr[] = [
$r('sys.media.ohos_ic_public_device_phone'),
$r('sys.media.ohos_ic_public_device_pad'),
$r('sys.media.ohos_ic_public_device_smartscreen'),
$r('sys.media.ohos_ic_public_device_matebook'),
$r('sys.media.ohos_ic_public_device_watch'),
$r('sys.media.ohos_ic_public_device_soundx_filled'),
];
@Prop isEnabled: boolean = false;
onChange?: (color: ResourceStr) => void;
private equals(icon1: ResourceStr, icon2: ResourceStr) {
const type1 = typeof icon1;
const type2 = typeof icon2;
if (type1 !== type2) {
return false;
}
if (type1 === 'object') {
return (icon1 as Resource).id === (icon2 as Resource).id;
}
return icon1 === icon2;
}
build() {
Row({ space: 12 }) {
ForEach(this.icons, (icon: ResourceStr) => {
Button() {
Image(icon)
.size({ width: 24, height: 24 })
.fillColor(this.equals(icon, this.icon) ? $r('sys.color.ohos_id_color_emphasize') :
$r('sys.color.ohos_id_color_text_secondary'))
.animation({ curve: Curve.Sharp, duration: 150 })
}
.type(ButtonType.Circle)
.backgroundColor(Color.Transparent)
.width(32)
.height(32)
.onClick(() => {
if (this.isEnabled) {
this.onChange?.(icon);
}
})
})
}
.width('100%')
.grayscale(this.isEnabled ? 0 : 1)
}
}
@Preview
@Component
struct IconPalettePreview {
build() {
IconPalette({})
}
}

View File

@ -0,0 +1,22 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export * from './ColorBlock';
export * from './IconBlock';
export * from './RadioBlock';
export * from './SliderBlock';

View File

@ -0,0 +1,3 @@
export const useEnabled = <T>(enabled: boolean, value: T, defaultValue: T | undefined = undefined) => {
return enabled ? value : defaultValue;
}

View File

@ -31,11 +31,10 @@ function IconButton(icon: Resource, action: () => void) {
@Component
export struct Drawer {
@Prop title: string;
@Prop @Require title: ResourceStr;
@Link showParameters: boolean
@BuilderParam content: () => void;
@BuilderParam parameters: () => void;
@Consume('router') router: NavPathStack
build() {
@ -86,7 +85,12 @@ export struct Drawer {
.borderRadius({ topLeft: 30, topRight: 30 })
.constraintSize({ maxWidth: 480, maxHeight: '70%', minHeight: '40%' })
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])
.padding({ left: 16, right: 16, top: 8, bottom: 32 })
.padding({
left: 16,
right: 16,
top: 8,
bottom: 32
})
.transition(TransitionEffect.move(TransitionEdge.BOTTOM))
.width('100%')
}

View File

@ -15,7 +15,7 @@
import curves from '@ohos.curves';
import { Route, RouteGroup } from '../common/route';
import { operatesRoute, OperatesDestination } from './operates';
import { OperatesDestination, operatesRoute } from './operates';
@Styles
function CardPressedStyle() {
@ -70,7 +70,12 @@ struct Index {
}
.borderRadius(20)
.width('100%')
.padding({ left: 8, right: 8, top: 18, bottom: 18 })
.padding({
left: 8,
right: 8,
top: 18,
bottom: 18
})
.enabled(!!route.children.length)
.stateStyles({
pressed: CardPressedStyle,
@ -121,7 +126,12 @@ struct Index {
disabled: CardDisabledStyle,
})
.borderRadius(20)
.padding({ left: 8, right: 8, top: 13, bottom: 13 })
.padding({
left: 8,
right: 8,
top: 13,
bottom: 13
})
.transition(
TransitionEffect.OPACITY.animation({
curve: curves.interpolatingSpring(0, 1, 228, 30)
@ -132,7 +142,7 @@ struct Index {
const name = `${routeGroup.name}/${route.name}`;
const pathNames = this.router.getAllPathName();
if (pathNames[pathNames.length-1] !== name) {
this.router.pushPath({ name });
this.router.pushPath({ name, param: route });
}
})
}

View File

@ -19,6 +19,7 @@ import promptAction from '@ohos.promptAction';
@Component
export struct ButtonBootcamp {
@Require @Prop title: ResourceStr;
@State showParameters: boolean = false
@State enableBtnType: boolean = false
@State btnType: ButtonType = ButtonType.Capsule
@ -44,7 +45,7 @@ export struct ButtonBootcamp {
build() {
NavDestination() {
Drawer({
title: '按钮/Button',
title: this.title,
showParameters: $showParameters,
content: () => {
this.Content()
@ -202,6 +203,8 @@ export struct ButtonBootcamp {
@Component
struct ButtonBootcampPreviewer {
build() {
ButtonBootcamp()
ButtonBootcamp({
title: '按钮/Button'
})
}
}

View File

@ -0,0 +1,216 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Drawer } from '../../components/Drawer';
import { ColorBlock, IconBlock, RadioBlock, useEnabled } from 'common';
import { Chip, ChipSize, PrefixIconOptions, SuffixIconOptions } from '@ohos.arkui.advanced.Chip';
@Component
export struct ChipBootcamp {
@Require @Prop title: ResourceStr;
@State showParameters: boolean = false;
@State enableActivated: boolean = false;
@State activated: boolean = false;
@State enableActivatedBackgroundColor: boolean = false;
@State activatedBackgroundColor: ResourceColor = $r('sys.color.ohos_id_color_emphasize');
@State enableInactivatedBackgroundColor: boolean = false;
@State inactivatedBackgroundColor: ResourceColor = $r('sys.color.ohos_id_color_emphasize');
@State enablePrefixIconActivatedFillColor: boolean = false;
@State prefixIconActivatedFillColor: ResourceColor = $r('sys.color.ohos_id_color_text_primary_contrary');
@State enableSuffixIconActivatedFillColor: boolean = false;
@State suffixIconActivatedFillColor: ResourceColor = $r('sys.color.ohos_id_color_text_primary_contrary');
@State enablePrefixIconInactivatedFillColor: boolean = false;
@State prefixIconInactivatedFillColor: ResourceColor = $r('sys.color.ohos_id_color_text_primary_contrary');
@State enableSuffixIconInactivatedFillColor: boolean = false;
@State suffixIconInactivatedFillColor: ResourceColor = $r('sys.color.ohos_id_color_text_primary_contrary');
@State enableActivatedFontColor: boolean = false;
@State activatedFontColor: ResourceColor = $r('sys.color.ohos_id_color_text_primary_contrary');
@State enableInactivatedFontColor: boolean = false;
@State inactivatedFontColor: ResourceColor = $r('sys.color.ohos_id_color_text_primary_contrary');
@State enableChipSize: boolean = false;
@State chipSize: ChipSize = ChipSize.NORMAL;
@State enablePrefixIcon: boolean = false;
@State prefixIcon: ResourceStr = $r('sys.media.ohos_ic_public_device_phone');
@State enableSuffixIcon: boolean = false;
@State suffixIcon: ResourceStr = $r('sys.media.ohos_ic_public_device_phone');
@State enableAllowClose: boolean = false;
@State allowClose: boolean = true;
build() {
NavDestination() {
Drawer({
title: this.title,
showParameters: $showParameters,
content: () => {
this.Content()
},
parameters: () => {
this.Parameters()
}
})
}
.backgroundColor($r('sys.color.ohos_id_color_sub_background'))
.hideTitleBar(true)
}
@Builder
Content() {
Column({ space: 40 }) {
Chip({
prefixIcon: useEnabled<PrefixIconOptions>(this.enablePrefixIcon, {
src: this.prefixIcon,
activatedFillColor: useEnabled(this.enablePrefixIconActivatedFillColor, this.prefixIconActivatedFillColor),
fillColor: useEnabled(this.enablePrefixIconInactivatedFillColor, this.prefixIconInactivatedFillColor),
}),
label: {
text: '操作块',
activatedFontColor: useEnabled(this.enableActivatedFontColor, this.activatedFontColor),
fontColor: useEnabled(this.enableInactivatedFontColor, this.inactivatedFontColor),
},
suffixIcon: useEnabled<SuffixIconOptions>(this.enableSuffixIcon, {
src: this.suffixIcon,
activatedFillColor: useEnabled(this.enableSuffixIconActivatedFillColor, this.suffixIconActivatedFillColor),
fillColor: useEnabled(this.enableSuffixIconInactivatedFillColor, this.suffixIconInactivatedFillColor),
}),
size: useEnabled(this.enableChipSize, this.chipSize),
allowClose: useEnabled(this.enableAllowClose, this.allowClose),
enabled: true,
activated: useEnabled(this.enableActivated, this.activated),
activatedBackgroundColor: useEnabled(this.enableActivatedBackgroundColor, this.activatedBackgroundColor),
backgroundColor: useEnabled(this.enableInactivatedBackgroundColor, this.inactivatedBackgroundColor),
})
}
}
@Builder
Parameters() {
Scroll() {
Column({ space: 8 }) {
RadioBlock({
title: '尺寸',
isEnabled: this.enableChipSize,
value: this.chipSize,
dataSource: [
{ label: '小尺寸', value: ChipSize.SMALL },
{ label: '正常尺寸', value: ChipSize.NORMAL },
]
})
RadioBlock({
title: '是否允许关闭',
isEnabled: this.enableAllowClose,
value: this.allowClose,
dataSource: [
{ label: '允许', value: true },
{ label: '禁止', value: false },
]
})
IconBlock({
title: '是否显示前缀图标',
isEnabled: this.enablePrefixIcon,
icon: this.prefixIcon,
})
IconBlock({
title: '是否显示后缀图标',
isEnabled: this.enableSuffixIcon,
icon: this.suffixIcon,
})
RadioBlock({
title: '是否激活',
isEnabled: this.enableActivated,
value: this.activated,
dataSource: [
{ label: '激活', value: true },
{ label: '去激活', value: false },
]
})
if (this.activated) {
ColorBlock({
title: '激活态背景色',
isEnabled: this.enableActivatedBackgroundColor,
color: this.activatedBackgroundColor,
})
ColorBlock({
title: '激活态字体颜色',
isEnabled: this.enableActivatedFontColor,
color: this.activatedFontColor,
})
if (this.enablePrefixIcon) {
ColorBlock({
title: '激活态前缀图标颜色',
isEnabled: this.enablePrefixIconActivatedFillColor,
color: this.prefixIconActivatedFillColor,
})
}
if (this.enableSuffixIcon) {
ColorBlock({
title: '激活态后缀图标颜色',
isEnabled: this.enableSuffixIconActivatedFillColor,
color: this.suffixIconActivatedFillColor,
})
}
} else {
ColorBlock({
title: '去激活态背景色',
isEnabled: this.enableInactivatedBackgroundColor,
color: this.inactivatedBackgroundColor,
})
ColorBlock({
title: '去激活态字体颜色',
isEnabled: this.enableInactivatedFontColor,
color: this.inactivatedFontColor,
})
if (this.enablePrefixIcon) {
ColorBlock({
title: '去激活态前缀图标颜色',
isEnabled: this.enablePrefixIconInactivatedFillColor,
color: this.prefixIconInactivatedFillColor,
})
}
if (this.enableSuffixIcon) {
ColorBlock({
title: '去激活态后缀图标颜色',
isEnabled: this.enableSuffixIconInactivatedFillColor,
color: this.suffixIconInactivatedFillColor,
})
}
}
}.width('100%')
}.height('50%')
}
}
@Preview
@Component
struct ChipBootcampPreviewer {
build() {
ChipBootcamp({
title: '操作块/Chip'
})
}
}

View File

@ -13,21 +13,25 @@
* limitations under the License.
*/
import { RouteGroup } from '../../common/route';
import { Route, RouteGroup } from '../../common/route';
import { ButtonBootcamp } from './ButtonBootcamp';
import { ChipBootcamp } from './ChipBootcamp';
export const operatesRoute: RouteGroup = {
name: 'operates',
label: '操作类',
children: [
{ name: 'button', label: '按钮/Button' },
{ name: 'chip', label: '操作块/Chip' },
]
};
@Builder
export function OperatesDestination(name: string) {
export function OperatesDestination(name: string, route: Route) {
if (name === 'operates/button') {
ButtonBootcamp()
ButtonBootcamp({ title: route.label })
} else if (name === 'operates/chip') {
ChipBootcamp({ title: route.label })
}
}