diff --git a/CHANGELOG.md b/CHANGELOG.md index 40a6b85..957f0d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,4 +8,5 @@ - add bubble - add indicator-page-point - add blur +- add radio - add toast \ No newline at end of file diff --git a/src/components/radio/README.md b/src/components/radio/README.md new file mode 100644 index 0000000..8f62960 --- /dev/null +++ b/src/components/radio/README.md @@ -0,0 +1,71 @@ +# star-radio and star-radio group +星光 Web 组件——单选框组件:radio组件介绍(8月31日) + + +## 介绍 +star-radio和star-radio-group为单选框按钮和单选框按钮组,一般在使用过程中都是同时使用。 +star-radio属性: + + ### 1、checkedType属性 + 单选框风格样式类型,checkedType="symbol"为默认类型(√),checkedType="round"为圆圈类型,后续根据具体要求可扩展定义 + ```html demo + + + + ``` + ### 2、checked属性 + Booloean类型,checked=true,单选框选中状态,checked=false,未选中状态。默认为false,不选中状态。 + ```html demo + + + + + ``` + ### 3、checkedLocation属性 + 单选框选中图标位置状态,checkedLocation="left" 选中图标在左侧栏,checkedLocation="right" 选中图标在右侧栏,默认在左侧栏 + ```html demo + + + + + ``` + ### 4、label属性 + UI界面中的正文主体文本内容 + ```html demo + + + label="content2" + + ``` + ### 5、node属性 + UI界面中的正文主体文本内容下方补充扩展文本内容 + ``` html demo + + + label="content2" label2="expand2" + + ``` + ### 6、icon属性 + 控制ui界面中的图标字体样式属性 + ```html demo + + + icon="keyboard" label="content2" label2="expand2" + + ``` + ### 7、iconcolor属性 + 控制图标字体颜色样式属性,和icon属性同时使用时起作用 + ```html demo + + + icon="keyboard" iconcolor="#226dee" label="content2" label2="expand2" + + ``` + ### 8、disabled属性 + 控制单选框按钮禁用状态,默认为:false。 + ```html demo + + + icon="keyboard" iconcolor="#226dee" label="content2" label2="expand2" disabled + + ``` \ No newline at end of file diff --git a/src/components/radio/radio-group.ts b/src/components/radio/radio-group.ts new file mode 100644 index 0000000..090affc --- /dev/null +++ b/src/components/radio/radio-group.ts @@ -0,0 +1,67 @@ +import {LitElement, html, CSSResultArray, PropertyValues} from 'lit' +import {customElement, property, queryAssignedNodes} from 'lit/decorators.js' +import './radio' +import {StarRadio} from './radio' +import {sharedStyles} from './radio-style' +@customElement('star-radio-group') +export class StarRadioGroup extends LitElement { + public static override get styles(): CSSResultArray { + return [sharedStyles] + } + @property() selected = '' + @property() checkedLocation = 'left' + @property() checkedType = '' + constructor() { + super() + const shadowRoot = this.attachShadow({mode: 'open'}) + shadowRoot.addEventListener('change', (event: Event) => { + event.stopPropagation() //阻止事件冒泡到父元素,阻止任何父事件处理程序被执行。 + // @ts-ignore + this.selected = event.target.value + this.radioChange(event.target) //重构event.target对象 + }) + } + @queryAssignedNodes() //用来获取对应的slot元素 + public defaultNodes!: Node[] + public get radios(): StarRadio[] { + return this.defaultNodes.filter( + (node) => (node as HTMLElement) instanceof StarRadio + ) as StarRadio[] + } + render() { + return html` +
+ +
+ ` + } + protected override firstUpdated(changes: PropertyValues): void { + super.firstUpdated(changes) + this.radios.map((radio) => { + radio.checkedLocation = this.checkedLocation + radio.checkedType = this.checkedType + radio.checked ? (this.selected = radio.value) : '' + }) + this.changeEvent() + } + // @ts-ignore + radioChange(checkedRadio) { + this.radios.map((radio) => { + radio.checked = this.selected === radio.value + }) + this.changeEvent() + } + protected changeEvent() { + this.dispatchEvent( + new Event('star-radio-change', { + bubbles: true, + composed: false, + }) + ) + } +} +declare global { + interface HTMLElementTagNameMap { + 'star-radio-group': StarRadioGroup + } +} \ No newline at end of file diff --git a/src/components/radio/radio-style.ts b/src/components/radio/radio-style.ts new file mode 100644 index 0000000..7682bb1 --- /dev/null +++ b/src/components/radio/radio-style.ts @@ -0,0 +1,76 @@ +import {css, CSSResult} from 'lit' +export const sharedStyles: CSSResult = css` + .star-radio { + display: flex; + cursor: pointer; + padding: 15px; + } + /*按钮禁用状态*/ + .star-radio.disabled { + color: #606266; + cursor: default; + pointer-events: none; + } + /*按钮选中状态*/ + .star-radio.checked { + display: flex; + cursor: pointer; + background-color: #b4c4e6; + } + .star-radio-main { + flex: 1; + display: flex; + align-items: center; + } + .star-radio-main.right { + flex-direction: row-reverse; + } + .star-radio .label-img { + flex: 1; + display: flex; + align-items: center; + } + /* 控制单选框显示的类型 */ + .star-radio .checktype { + margin: 0 12px; + /* text-align: center; */ + } + .star-radio .checkedType.symbol { + color: #1561f0; + font-weight: bold; + width: 20px; + height: 20px; + } + .star-radio .checkedType.round { + box-sizing: border-box; + display: inline-block; + border-radius: 50%; + width: 20px; + height: 20px; + background-color: #dedede; + } + .star-radio.checked .checkedType.round { + border: 6px solid #1a60e2; + } + /*控制图标*/ + .star-radio .srcImg { + margin: 10px; + font-size: 25px; + font-family: 'gaia-icons'; + text-align: center; + } + /*控制label*/ + .star-radio .label { + display: flex; + flex-direction: column; + } + .star-radio .label .label1 { + font-size: 16px; + } + .star-radio .label .note { + font-size: 12px; + } + .star-radio.checked .label { + color: #1561f0; + } +` \ No newline at end of file diff --git a/src/components/radio/radio.ts b/src/components/radio/radio.ts new file mode 100644 index 0000000..65f1752 --- /dev/null +++ b/src/components/radio/radio.ts @@ -0,0 +1,87 @@ +import {LitElement, html, CSSResultArray} from 'lit' +import {customElement, property} from 'lit/decorators.js' +import {sharedStyles} from './radio-style' +@customElement('star-radio') +export class StarRadio extends LitElement { + public static override get styles(): CSSResultArray { + return [sharedStyles] + } + @property({type: String}) checkedType = '' + @property({type: Boolean}) checked = false + @property({type: Boolean}) disabled = false + @property({type: String}) checkedLocation = 'left' + @property({type: String}) label = '' + @property({type: String}) note = '' + @property({type: String}) icon = '' + @property({type: String}) iconcolor = '' + @property({type: String}) value = '' + render() { + return html` +
+
+ ${this.checkedTypeFun()} +
+ ${this.icon + ? html` + ${this.icon} + ` + : ''} + ${this.iconcolor + ? html` + + ` + : ''} + + ${this.label} + ${this.note + ? html` + ${this.note} + ` + : ''} + +
+
+
+ ` + } + protected radioActivate() { + if (this.checked) return + this.checked = true + this.dispatchEvent( + new Event('change', { + bubbles: true, //向上冒泡 + composed: false, //事件不会在ShadowDOM根节点之外触发侦听器 + }) + ) + } + checkedTypeFun() { + if (this.checkedType === 'symbol') { + return html` + ${this.checked ? `√` : ''} + ` + } else if (this.checkedType === 'round') { + return html` + + ` + } else { + return html` + ${this.checked ? `√` : ''} + ` + } + } +} +declare global { + interface HTMLElementTagNameMap { + 'star-radio': StarRadio + } +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 9b18039..9de3d75 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,6 +8,8 @@ import {StarAnimateSection} from './components/section/section' import './components/section/section' import './test/panels/root' import './components/button/button' +import './components/radio/radio-group' +import './components/radio/radio' import './components/toast/toast' import './components/picker/picker' @customElement('settings-app') diff --git a/src/test/panels/radio/radio.ts b/src/test/panels/radio/radio.ts new file mode 100644 index 0000000..a35f21a --- /dev/null +++ b/src/test/panels/radio/radio.ts @@ -0,0 +1,153 @@ +import {html, LitElement, CSSResultArray} from 'lit' +import {customElement, property, state} from 'lit/decorators.js' +@customElement('panel-radio') +export class PanelRadio extends LitElement { + @property() + foo = '' + @state() + bar = '' + @state() + addNumber = 0 + constructor() { + super() + const shadowRoot = this.attachShadow({mode: 'open'}) + shadowRoot.addEventListener('star-radio-change', (event: Event) => { + event.stopPropagation() + // @ts-ignore + console.log('选择的单选框value : ' + event.target.__selected) + }) + } + render() { + return html` +
+
+
自动锁屏
+ + + + + + +
+
+
+
+
模式选择
+ + + + +
+
+
+
+
色彩风格
+ + + + + +
+
+
+
+
自动填充服务
+ + + + + +
+
+
+
+
禁用状态测试
+ + + + +
+
+ ` + } + public static override get styles(): CSSResultArray { + return [] + } +} +declare global { + interface HTMLElementTagNameMap { + 'panel-radio': PanelRadio + } +} \ No newline at end of file diff --git a/src/test/panels/root.ts b/src/test/panels/root.ts index 56bbe24..80b5c0f 100644 --- a/src/test/panels/root.ts +++ b/src/test/panels/root.ts @@ -13,6 +13,8 @@ import './indicators/indicators' import './blur/use-blur' import './button/button' import './container/container' +import './radio/radio' + import './toast/toast' import './picker/picker' type SEID = string @@ -119,6 +121,14 @@ export class PanelRoot extends LitElement { href="#button" >
+ +