diff --git a/index.html b/index.html index 2490e1b..47592cd 100644 --- a/index.html +++ b/index.html @@ -34,32 +34,6 @@ font-weight: 500; font-style: normal; } - - :root { - --left-transform: -100vw; - --right-transform: +100vw; - --li-base-height: 43px; - --li-left-padding: 10px; - --li-right-padding: 10px; - --blur-image: ''; - --blur-radius-factor: 20; - --blur-radius: calc(1px * var(--blur-radius-factor)); - --blur-scale-base-factor: 1.05; - --blur-scale-factor: calc( - var(--blur-scale-base-factor) + (var(--blur-radius-factor) - 20) * - 0.0025 - ); - } - - /* for nanopcT4 */ - @media (max-width: 500px) { - :root { - --blur-radius-factor: 5; - --blur-scale-factor: calc( - var(--blur-scale-base-factor) + (var(--blur-radius-factor)) * 0.005 - ); - } - } diff --git a/src/components/asset/icons/index.ts b/src/components/asset/icons/index.ts new file mode 100644 index 0000000..ee54a0f --- /dev/null +++ b/src/components/asset/icons/index.ts @@ -0,0 +1,247 @@ +import {html} from 'lit' + +// 主题 +export const store = html` + + + + + + + + + + + +` + +// 图标 +export const app = html` + + + + + + + + + + + + + + + + + + + +` + +// 桌面壁纸 +export const desktopWallpaper = html` + + + + + + + + + + + + + + + + + + + + + + + + +` + +// 锁屏 +export const lockscreen = html` + + + + + + + + + + + + + + + + + + + +` + +// 隐私 +export const privacy = html` + + + + + + + + + + + + + + + + + + + +` +export type stackInstances = typeof store + +export default { + store, + app, + desktopWallpaper, + lockscreen, + privacy, +} as { + [key: string]: stackInstances +} diff --git a/src/components/asset/svg-icon.ts b/src/components/asset/svg-icon.ts new file mode 100644 index 0000000..34a6665 --- /dev/null +++ b/src/components/asset/svg-icon.ts @@ -0,0 +1,37 @@ +import {html, LitElement, css} from 'lit' +import {customElement, property} from 'lit/decorators.js' +import icons from './icons/index' + +@customElement('star-svg-icon') +export class StarSvgIcon extends LitElement { + @property({type: Number}) width = 24 + @property({type: Number}) height = 24 + @property({type: String}) symbol = 'privacy' + + render() { + const iconpath = icons[this.symbol] + return html` + + ${iconpath} + + ` + } + + static styles = css` + :host { + display: flex; + } + ` +} + +declare global { + interface HTMLElementTagNameMap { + 'star-svg-icon': StarSvgIcon + } +} diff --git a/src/components/base/base-style.ts b/src/components/base/base-style.ts new file mode 100644 index 0000000..a96cde2 --- /dev/null +++ b/src/components/base/base-style.ts @@ -0,0 +1,107 @@ +import {css, CSSResult} from 'lit' + +export const baseStyles: CSSResult = css` + :host { + /* 文字/正文黑 */ + --font-main-black: #292929; + /* 文字/辅助字-黑 */ + --font-auxiliary-black: rgba(38, 38, 38, 0.5); + /* 文字/标题黑 */ + --font-heading-black: #4d4d4d; + + /* 文字/正文白 */ + --font-main-white: #f0f0f0; + /* 文字/高亮白 */ + --font-highlight-white: #fafafa; + /* 文字/辅助字-白 */ + --font-auxiliary-white: rgba(245, 245, 245, 0.5); + + /* 倒角 */ + --base-menu-radius: 16px; + --base-dialog-radius: 20px; + --base-border-radius: 34px; + + /* 线性图标/32及以下-常规黑 */ + --icon-regular: #333333; + + /* 分隔符 */ + --split-line: #cfd8e8; + + /* 主题色/蓝 */ + --theme-blue: #1d98f0; + /* 主题色/红 */ + --theme-red: #ec4949; + + --pure-white: #ffffff; + + --font-main-size: 14px; + /* --font-main-weight: 400; */ + --font-main-weight: bold; + + --line-height: calc(3 * var(--font-main-size)); + + --li-left-padding: 10px; + --li-right-padding: 10px; + --li-base-height: 43px; + + /***********默认浅色**************/ + /* 商务/组件浅/白调-斜线渐变 */ + --bg-dialog-gradient: linear-gradient( + 137.64deg, + #f5f0f5 0%, + #fafafa 20.46%, + #d5daf2 90.45% + ); + /* 底色/弹窗浅 */ + --bg-dialog: linear-gradient( + 134.78deg, + #f7f5f7 2.34%, + #fafafa 34.11%, + #e1e4f2 100% + ); + /* 全/ hover_lm */ + --bg-hover: rgba(0, 0, 0, 0.06); + --bg-gray-button: rgba(51, 51, 51, 0.06); + --bg-icon-button: rgba(255, 255, 255, 0.68); + + --bg-button: rgba(247, 247, 247, 0.75); + } + + @media (prefers-color-scheme: light) { + :host { + /* 底色/弹窗浅 */ + --bg-dialog: linear-gradient( + 134.78deg, + #f7f5f7 2.34%, + #fafafa 34.11%, + #e1e4f2 100% + ); + /* 商务/组件浅/白调-斜线渐变 */ + --bg-dialog-gradient: linear-gradient( + 137.64deg, + #f5f0f5 0%, + #fafafa 20.46%, + #d5daf2 90.45% + ); + + /* 全/ hover_lm */ + --bg-hover: rgba(0, 0, 0, 0.06); + --bg-button: rgba(247, 247, 247, 0.75); + --bg-gray-button: rgba(51, 51, 51, 0.06); + --bg-icon-button: rgba(255, 255, 255, 0.68); + } + } + + @media (prefers-color-scheme: dark) { + :host { + /* 底色/弹窗深 */ + --bg-dialog: linear-gradient(101.98deg, #4e5161 1.12%, #363a47 96.75%); + + /* 全/ hover_dm */ + --bg-hover: rgba(255, 255, 255, 0.09); + --bg-button: rgba(64, 64, 64, 0.7); + --bg-gray-button: rgba(228, 228, 228, 0.1); + --bg-icon-button: rgba(0, 0, 0, 0.3); + } + } +` diff --git a/src/components/blur/blur.ts b/src/components/blur/blur.ts index eb110f9..e2c3ce1 100644 --- a/src/components/blur/blur.ts +++ b/src/components/blur/blur.ts @@ -12,7 +12,7 @@ export class StarBlur extends LitElement { if (name === 'imagesrc') { if (!this.imagesrc) console.error('StarBlur has no imagesrc') - document.documentElement.style.setProperty('--blur-image', this.imagesrc) + this.style.setProperty('--blur-image', this.imagesrc) } } @@ -28,6 +28,15 @@ export class StarBlur extends LitElement { static styles = css` :host { + --blur-image: ''; + --blur-radius-factor: 20; + --blur-radius: calc(1px * var(--blur-radius-factor)); + --blur-scale-base-factor: 1.05; + --blur-scale-factor: calc( + var(--blur-scale-base-factor) + (var(--blur-radius-factor) - 20) * + 0.0025 + ); + position: absolute; width: 100vw; height: 100vh; @@ -35,6 +44,15 @@ export class StarBlur extends LitElement { top: 0; overflow: hidden; } + /* for nanopcT4 */ + @media (max-width: 500px) { + :host { + --blur-radius-factor: 5; + --blur-scale-factor: calc( + var(--blur-scale-base-factor) + (var(--blur-radius-factor)) * 0.005 + ); + } + } #blur-mask { position: absolute; width: inherit; diff --git a/src/components/bubble/bubble.ts b/src/components/bubble/bubble.ts index 4f9c055..125f108 100644 --- a/src/components/bubble/bubble.ts +++ b/src/components/bubble/bubble.ts @@ -27,6 +27,8 @@ export class StarBubble extends LitElement { static styles = css` :host { + --li-base-height: 43px; + display: inline-block; width: calc(var(--li-base-height) - 16px); /* 尽量节省宽度 */ height: var(--li-base-height); diff --git a/src/components/button/README.md b/src/components/button/README.md index c09d92d..9c85844 100644 --- a/src/components/button/README.md +++ b/src/components/button/README.md @@ -1,6 +1,25 @@ # star-button -星光 Web 组件——按钮组件:本组件样式及代码风格依然在完善阶段,现阶段介绍如下(8 月 27 日) +星光按钮组件:本组件样式及代码风格依然在完善阶段,现阶段介绍如下(8 月 27 日) + +## 参照设计稿 + +基础原则: + +1. 按钮的 +2. 按钮具备大小属性(small,medium,large,extralarge) +3. 按钮中的图标位于左侧,图标应是可选的;如果存在图标,则文字是可选的,对应图标按钮。 + +默认值: + +1. 按钮底色:无色 +2. 按钮文字颜色:正文黑 +3. 按钮文字:确定 + +按钮类型 1:(无底色 + 文字(带颜色 白|黑|蓝|红|灰))的自适应矩形块, 用于弹窗按钮、菜单按钮 +按钮类型 2:(给定底色 + 图标)的圆形块, 用于工具按钮(如通知栏左滑处,任务管理器关闭处) +按钮类型 3:(给定底色 + 文字)的倒角矩形块, 用于强调按钮(如主题选择) +按钮类型 4:(图标 + 文字)的矩形块, 用于菜单按钮、主题选择处 ## 介绍 @@ -8,7 +27,7 @@ star-button 属性: 1. type:按钮类型,包括文本按钮 base、图标文本按钮 iconlabel 和图标按钮 icononly。 -```html demo +```html @@ -16,14 +35,14 @@ star-button 属性: 2. variant:按钮样式,包括 accent、primary、secondary、negative、black 和 white,默认为 accent。 -```html demo +```html ``` 3. size:控制按钮大小,包括 small、medium、large 和 extralarge 四种,默认为 medium。 -```html demo +```html ``` 5. disabled:控制按钮禁用状态,默认为:false。 -```html demo +```html ``` 6. treatment:控制按钮填充状态,包括 fill 和 outline,默认为:fill。 -```html demo +```html + return html` + - ` - } else { - return html` - - ` - } + + + ` } getIconLabelButton(): HTMLTemplateResult { - const colorstyle = this.iconcolor - ? html` - - ` - : nothing - if (this.hasAttribute('disabled')) { - return html` - - ` - } else { - return html` - - ` - } + return html` + + ` } getIconOnlyButton(): HTMLTemplateResult { - const colorstyle = this.iconcolor - ? html` - - ` - : nothing - if (this.hasAttribute('disabled')) { - return html` - - ` - } else { - return html` - - ` - } + return html` + + ` } getConfirmButton(): HTMLTemplateResult { return html` diff --git a/src/components/li/li.ts b/src/components/li/li.ts index ac5a71c..80e1041 100644 --- a/src/components/li/li.ts +++ b/src/components/li/li.ts @@ -1,5 +1,13 @@ -import {html, css, LitElement, HTMLTemplateResult, nothing} from 'lit' +import { + html, + css, + CSSResultArray, + LitElement, + HTMLTemplateResult, + nothing, +} from 'lit' import {customElement, property} from 'lit/decorators.js' +import {baseStyles} from '../base/base-style' import '../bubble/bubble' import '../switch/switch' @@ -277,92 +285,98 @@ export class StarLi extends LitElement { return nothing } } - - static styles = css` - :host { - width: inherit; - } - li { - width: inherit; - display: flex; - min-height: var(--li-base-height); - line-height: var(--li-base-height); - padding-inline-start: var(--li-left-padding); - padding-inline-end: var( - --li-right-padding - ); /* right-arrow须与最右侧文字对齐 */ - } - /* right-arrow须与最右侧文字对齐 */ - /* li.hashref { + public static override get styles(): CSSResultArray { + return [ + baseStyles, + css` + :host { + width: inherit; + border-radius: var(--base-border-radius); + } + li { + width: inherit; + display: flex; + border-radius: var(--base-border-radius); + min-height: var(--li-base-height); + line-height: var(--li-base-height); + padding-inline-start: var(--li-left-padding); + padding-inline-end: var( + --li-right-padding + ); /* right-arrow须与最右侧文字对齐 */ + } + /* right-arrow须与最右侧文字对齐 */ + /* li.hashref { padding-inline-end: 0; } */ - a { - display: flex; - text-decoration: none; - color: #000; - width: 100%; - } - a.hasicon::before, - a.hashref::after { - flex: 1; - font-size: 25px; - min-width: 25px; - max-width: 25px; - font-family: 'gaia-icons'; - } - a.hasicon::before { - color: #657073; - text-align: left; - content: attr(data-icon); - padding-inline-end: var(--li-right-padding); - } - a.hashref::after { - color: #a5acae; - text-align: right; - content: 'right-light'; - } - input { - width: 100vw; - max-width: 500px; - padding: 0; - border: 0; - height: inherit; - outline: none; - box-sizing: border-box; - vertical-align: top; - border-radius: 6px; - background-color: transparent; - font-size: 16px; - } - span.infokey, - span.label { - flex: 1; - text-align: left; - } - span.infovalue { - /* flex: 1; */ /* 利用自动挤压 */ - text-align: right; - color: #aaa; - } - span.onlyread { - color: #aaa; - font-size: clamp(0.55rem, 2.3vw, 1.2rem); - } - span.text { - flex: 8; - text-align: left; - } - span.bubble { - flex: 1; - height: inherit; - background-color: red; - } - span.next { - flex: 1; - text-align: right; - color: #aaa; - } - ` + a { + display: flex; + text-decoration: none; + color: #000; + width: 100%; + } + a.hasicon::before, + a.hashref::after { + flex: 1; + font-size: 25px; + min-width: 25px; + max-width: 25px; + font-family: 'gaia-icons'; + } + a.hasicon::before { + color: #657073; + text-align: left; + content: attr(data-icon); + padding-inline-end: var(--li-right-padding); + } + a.hashref::after { + color: #a5acae; + text-align: right; + content: 'right-light'; + } + input { + width: 100vw; + max-width: 500px; + padding: 0; + border: 0; + height: inherit; + outline: none; + box-sizing: border-box; + vertical-align: top; + border-radius: 6px; + background-color: transparent; + font-size: 16px; + } + span.infokey, + span.label { + flex: 1; + text-align: left; + } + span.infovalue { + /* flex: 1; */ /* 利用自动挤压 */ + text-align: right; + color: #aaa; + } + span.onlyread { + color: #aaa; + font-size: clamp(0.55rem, 2.3vw, 1.2rem); + } + span.text { + flex: 8; + text-align: left; + } + span.bubble { + flex: 1; + height: inherit; + background-color: red; + } + span.next { + flex: 1; + text-align: right; + color: #aaa; + } + `, + ] + } } declare global { diff --git a/src/components/ul/ul.ts b/src/components/ul/ul.ts index 0315643..043ee01 100644 --- a/src/components/ul/ul.ts +++ b/src/components/ul/ul.ts @@ -1,4 +1,12 @@ -import {html, css, LitElement, HTMLTemplateResult, nothing} from 'lit' +import { + html, + css, + CSSResultArray, + LitElement, + HTMLTemplateResult, + nothing, +} from 'lit' +import {baseStyles} from '../base/base-style' import {customElement, property} from 'lit/decorators.js' import {unsafeHTML} from 'lit/directives/unsafe-html.js' @@ -14,6 +22,7 @@ export class StarUl extends LitElement { @property({type: String}) type = '' @property({type: String}) title = '' @property({type: String}) text = '' + @property({type: String}) background = '' getbase(): HTMLTemplateResult { return html` @@ -77,6 +86,10 @@ export class StarUl extends LitElement { return nothing } + if (this.background) { + this.style.setProperty('--bg-ul', this.background) + } + switch (this.type) { case UlType.BASE: return this.getbase() @@ -92,46 +105,51 @@ export class StarUl extends LitElement { } } - static styles = css` - :host { - width: inherit; - display: block; - margin: 20px auto; - max-width: 88vw; - } + public static override get styles(): CSSResultArray { + return [ + baseStyles, + css` + :host { + width: inherit; + display: block; + margin: 20px auto; + max-width: 88vw; + } - ul { - list-style: none; - flex-direction: column; - display: flex; - width: 88vw; - padding: 0; - margin: 10px auto; - max-width: 88vw; - background: #fff; - box-shadow: rgb(64 60 67 / 16%) 1px 1px 5px 1px; - border-radius: 10px; - } + ul { + list-style: none; + flex-direction: column; + display: flex; + width: 100%; + padding: 0; + margin: 10px auto; + max-width: 88vw; + background: var(--bg-ul, var(--pure-white)); + box-shadow: rgb(64 60 67 / 16%) 1px 1px 5px 1px; + border-radius: inherit; /* 外部传入 */ + } - header, - footer { - color: #888; - margin-left: 10px; - font-size: 12px; - } + header, + footer { + color: #888; + margin-left: 10px; + font-size: 12px; + } - star-ul-base { - margin: 8px 0 12px 0; /* override child(star-ul-base) */ - } + star-ul-base { + margin: 8px 0 12px 0; /* override child(star-ul-base) */ + } - footer a { - text-decoration: unset; - } + footer a { + text-decoration: unset; + } - footer a:visited { - color: blue; - } - ` + footer a:visited { + color: blue; + } + `, + ] + } } declare global { diff --git a/src/index.ts b/src/index.ts index 48145d8..59dba4c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -144,6 +144,9 @@ export class SettingsApp extends LitElement { static styles = css` :host { + --left-transform: -100vw; + --right-transform: +100vw; + position: absolute; width: 100vw; } diff --git a/src/test/panels/blur/use-blur.ts b/src/test/panels/blur/use-blur.ts index 92174ba..b498c24 100644 --- a/src/test/panels/blur/use-blur.ts +++ b/src/test/panels/blur/use-blur.ts @@ -1,6 +1,7 @@ import {html, css, LitElement, TemplateResult} from 'lit' -import {customElement, state} from 'lit/decorators.js' +import {customElement, query, state} from 'lit/decorators.js' import '../../../components/blur/blur' +import {StarBlur} from '../../../components/blur/blur' @customElement('panel-blur') export class PanelBlur extends LitElement { @@ -8,6 +9,8 @@ export class PanelBlur extends LitElement { @state() backgroundImage = '' + @query('star-blur') myblur!: StarBlur + handleInputFile(evt: Event) { const imgfile = (evt.target as HTMLInputElement).files?.[0] if (imgfile) { @@ -16,7 +19,7 @@ export class PanelBlur extends LitElement { } handleInputRange(evt: Event) { - document.documentElement.style.setProperty( + this.myblur.style.setProperty( '--blur-radius-factor', (evt.target as HTMLInputElement).value ) diff --git a/src/test/panels/button/button.ts b/src/test/panels/button/button.ts index ce5b62b..b99e107 100644 --- a/src/test/panels/button/button.ts +++ b/src/test/panels/button/button.ts @@ -1,191 +1,162 @@ -import {html, LitElement} from 'lit' -import {customElement, eventOptions} from 'lit/decorators.js' -import {StarButton} from '../../../components/button/button' +import {html, css, CSSResultArray, LitElement} from 'lit' +import {customElement} from 'lit/decorators.js' +import {baseStyles} from '../../../components/base/base-style' import '../../../components/button-group/buttongroup' +import '../../../components/asset/svg-icon' @customElement('panel-button') export class PanelButton extends LitElement { - @eventOptions({passive: false}) - handleEvent(evt: Event) { - switch (evt.type) { - case 'click': - if ((evt.target as StarButton).label === 'Click') { - alert('这是一次点击事件测试') - } - break - } - } - render() { return html` -
-

按钮类型属性展示

- - - - - - - -
-
-

按钮大小属性展示

- - - - -
-
-

按钮填充状态展示

- - -
-
-

按钮点击事件展示

- -
-
-

图标按钮展示

+ + + + + + + + + + + | + + + + + + + + + + + + + + | + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - -
-
-

各类按钮属性在禁用状态下的展示

- - + + + - -
-
-

按钮组

- - - - - -
- - - - - -
+ + + + + + + + + + + + + + + + + ` } + + static get styles(): CSSResultArray { + return [ + baseStyles, + css` + star-ul#dialog { + border-radius: var(--base-dialog-radius); + } + star-ul#menu { + max-width: 300px; + border-radius: var(--base-menu-radius); + } + star-ul#iconmenu { + max-width: 150px; + border-radius: var(--base-menu-radius); + } + star-ul#dialog { + border-radius: var(--base-menu-radius); + } + star-li span.split { + color: var(--split-line); + } + `, + ] + } } declare global { diff --git a/src/test/panels/switch-styles.ts b/src/test/panels/switch-styles.ts index b73cebe..b5848c6 100644 --- a/src/test/panels/switch-styles.ts +++ b/src/test/panels/switch-styles.ts @@ -14,12 +14,4 @@ export const switchStyles: CSSResult = css` padding: 0; background: #f0f0f0; } - - :root { - --left-transform: -100vw; - --right-transform: +100vw; - --li-base-height: 43px; - --li-left-padding: 10px; - --li-right-padding: 10px; - } `