@iyulab/modern-app 0.12.0 → 0.14.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.
- package/CHANGELOG.md +32 -0
- package/dist/components/InfoField.d.ts +16 -1
- package/dist/components/InfoField.js +11 -7
- package/dist/components/SidebarButton.d.ts +5 -0
- package/dist/components/SidebarButton.js +2 -1
- package/dist/components/SidebarGroup.d.ts +3 -0
- package/dist/components/SidebarGroup.js +2 -1
- package/dist/components/SidebarLink.d.ts +3 -0
- package/dist/components/SidebarLink.js +2 -1
- package/dist/components/SidebarLink.styles.js +6 -1
- package/dist/layouts/SidebarLayout.js +3 -0
- package/package.json +2 -2
- package/skills/modern-app/references/components/info-field.md +6 -0
- package/skills/modern-app/references/layout.md +3 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.14.0] - 2026-08-10
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **`SidebarButtonConfig`, `SidebarLinkConfig`, and `SidebarGroupConfig` accept `lib?: string`.**
|
|
8
|
+
When set, `icon` resolves through `@iyulab/components`' `IconRegistry.resolve(lib, name)`
|
|
9
|
+
(a named, registered icon library) instead of only the default URL-fetch fallback path.
|
|
10
|
+
Existing usage without `lib` is unaffected.
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **`SidebarLink` selected-state icon color no longer gets overridden by a consumer-set
|
|
15
|
+
icon tint.** Adds a `--link-icon-color` custom property and a `:host([selected]) u-icon`
|
|
16
|
+
rule so the selected state's contrast wins regardless of an inherited or inline icon
|
|
17
|
+
color.
|
|
18
|
+
|
|
19
|
+
## [0.13.0] - 2026-08-08
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- **`u-info-field` accepts `format` (`'number' | 'currency' | 'date'`) and `currency`.**
|
|
24
|
+
When set, the value renders through `@iyulab/components`' `formatNumber`/`formatCurrency`/
|
|
25
|
+
`formatDate` instead of a plain `String(value)`, and `format="number"`/`"currency"` implies
|
|
26
|
+
the existing `numeric` (right-aligned, tabular-nums) styling automatically. `currency` has
|
|
27
|
+
no default — omitting it while `format="currency"` degrades to plain number formatting
|
|
28
|
+
rather than throwing. Existing usage without `format` is unaffected.
|
|
29
|
+
|
|
30
|
+
### Changed
|
|
31
|
+
|
|
32
|
+
- **`@iyulab/components` dependency floor raised to `^1.27.0`** (the feature above needs
|
|
33
|
+
`formatNumber`/`formatCurrency`/`formatDate`, added in that release).
|
|
34
|
+
|
|
3
35
|
## [0.12.0] - 2026-08-07
|
|
4
36
|
|
|
5
37
|
### Added
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { StyledElement } from '../internals/StyledElement.js';
|
|
2
2
|
type ElementParts = 'host' | 'label' | 'value';
|
|
3
|
+
export type InfoFieldFormat = 'number' | 'currency' | 'date';
|
|
3
4
|
/** 값이 "아직 없음"인가 — `0` 과 `false` 는 **값이다**. */
|
|
4
5
|
export declare function isBlank(v: unknown): boolean;
|
|
5
6
|
/**
|
|
@@ -16,6 +17,7 @@ export declare function isBlank(v: unknown): boolean;
|
|
|
16
17
|
* ```html
|
|
17
18
|
* <u-info-field label="부수" .value=${order.quantity} numeric></u-info-field>
|
|
18
19
|
* <u-info-field label="거래처">동서인쇄</u-info-field> <!-- 슬롯이 value 를 이긴다 -->
|
|
20
|
+
* <u-info-field label="합계" format="currency" currency="KRW" .value=${order.total}></u-info-field>
|
|
19
21
|
* ```
|
|
20
22
|
*/
|
|
21
23
|
export declare class InfoField extends StyledElement<ElementParts> {
|
|
@@ -27,7 +29,8 @@ export declare class InfoField extends StyledElement<ElementParts> {
|
|
|
27
29
|
* ⚠`0`·`false` 는 **대체되지 않는다** — 값이기 때문이다.
|
|
28
30
|
* 속성(`value="…"`)과 프로퍼티(`.value=`) 둘 다 받는다 — HTML 속성은 항상 문자열이라
|
|
29
31
|
* `type: String` 변환기가 붙어도 `.value=${order.quantity}` 같은 비-문자열 프로퍼티
|
|
30
|
-
* 바인딩은 그대로 통과한다(변환기는 속성 파싱에만 관여한다). 렌더는
|
|
32
|
+
* 바인딩은 그대로 통과한다(변환기는 속성 파싱에만 관여한다). 렌더는 `format` 이 없으면
|
|
33
|
+
* 항상 `String(value)`.
|
|
31
34
|
*/
|
|
32
35
|
value?: unknown;
|
|
33
36
|
/** "아직 없음"을 나타낼 문구. */
|
|
@@ -35,9 +38,21 @@ export declare class InfoField extends StyledElement<ElementParts> {
|
|
|
35
38
|
/**
|
|
36
39
|
* 숫자 값 — 우정렬 + 고정폭 숫자(`tabular-nums`).
|
|
37
40
|
* ★자릿수가 세로로 맞아야 크기 비교가 눈으로 된다. LOB 화면은 금액·수량이 절반이다.
|
|
41
|
+
* `format` 이 `'number'`/`'currency'` 면 이 정렬이 자동으로 함의된다 — 따로 켤 필요 없다.
|
|
38
42
|
*/
|
|
39
43
|
numeric: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Renders the value through `@iyulab/components`' `formatNumber`/`formatCurrency`/
|
|
46
|
+
* `formatDate`. When unset (default), falls back to plain `String(value)` as before.
|
|
47
|
+
*/
|
|
48
|
+
format?: InfoFieldFormat;
|
|
49
|
+
/**
|
|
50
|
+
* Currency code to use when `format="currency"` (e.g. `'KRW'`). **No default** — if
|
|
51
|
+
* omitted, degrades to plain number formatting without a currency symbol (does not throw).
|
|
52
|
+
*/
|
|
53
|
+
currency?: string;
|
|
40
54
|
private get hasSlotted();
|
|
55
|
+
private formatValue;
|
|
41
56
|
render(): import('lit-html').TemplateResult<1>;
|
|
42
57
|
}
|
|
43
58
|
declare global {
|
|
@@ -4,11 +4,12 @@ import { StyledElement as n } from "../internals/StyledElement.js";
|
|
|
4
4
|
import { styles as r } from "./InfoField.styles.js";
|
|
5
5
|
import { html as i } from "lit";
|
|
6
6
|
import { customElement as a, property as o } from "lit/decorators.js";
|
|
7
|
+
import { formatCurrency as s, formatDate as c, formatNumber as l } from "@iyulab/components";
|
|
7
8
|
//#region src/components/InfoField.ts
|
|
8
|
-
function
|
|
9
|
+
function u(e) {
|
|
9
10
|
return e == null || typeof e == "string" && e.trim() === "";
|
|
10
11
|
}
|
|
11
|
-
var
|
|
12
|
+
var d = class extends n {
|
|
12
13
|
constructor(...e) {
|
|
13
14
|
super(...e), this.label = "", this.blank = "—", this.numeric = !1;
|
|
14
15
|
}
|
|
@@ -18,16 +19,19 @@ var c = class extends n {
|
|
|
18
19
|
get hasSlotted() {
|
|
19
20
|
return this.childNodes.length > 0 && [...this.childNodes].some((e) => e.nodeType !== Node.TEXT_NODE || (e.textContent ?? "").trim() !== "");
|
|
20
21
|
}
|
|
22
|
+
formatValue() {
|
|
23
|
+
return this.format === "currency" ? this.currency ? s(Number(this.value), this.currency) : l(Number(this.value)) : this.format === "number" ? l(Number(this.value)) : this.format === "date" ? c(this.value) : String(this.value);
|
|
24
|
+
}
|
|
21
25
|
render() {
|
|
22
|
-
let e = !this.hasSlotted &&
|
|
26
|
+
let e = !this.hasSlotted && u(this.value), t = this.numeric || this.format === "number" || this.format === "currency";
|
|
23
27
|
return i`
|
|
24
28
|
<div class="label" part="label">${this.label}</div>
|
|
25
|
-
<div class="value ${
|
|
26
|
-
${this.hasSlotted ? i`<slot></slot>` : e ? this.blank :
|
|
29
|
+
<div class="value ${t ? "numeric" : ""} ${e ? "blank" : ""}" part="value">
|
|
30
|
+
${this.hasSlotted ? i`<slot></slot>` : e ? this.blank : this.formatValue()}
|
|
27
31
|
</div>
|
|
28
32
|
`;
|
|
29
33
|
}
|
|
30
34
|
};
|
|
31
|
-
t([o({ type: String }), e("design:type", Object)],
|
|
35
|
+
t([o({ type: String }), e("design:type", Object)], d.prototype, "label", void 0), t([o({ type: String }), e("design:type", Object)], d.prototype, "value", void 0), t([o({ type: String }), e("design:type", Object)], d.prototype, "blank", void 0), t([o({ type: Boolean }), e("design:type", Object)], d.prototype, "numeric", void 0), t([o({ type: String }), e("design:type", Object)], d.prototype, "format", void 0), t([o({ type: String }), e("design:type", String)], d.prototype, "currency", void 0), d = t([a("u-info-field")], d);
|
|
32
36
|
//#endregion
|
|
33
|
-
export {
|
|
37
|
+
export { d as InfoField, u as isBlank };
|
|
@@ -7,6 +7,9 @@ type ElementParts = 'host' | 'base' | 'icon' | 'label';
|
|
|
7
7
|
export interface SidebarButtonConfig extends SidebarPermissionGuard {
|
|
8
8
|
type: 'button';
|
|
9
9
|
icon?: string;
|
|
10
|
+
/** `icon`을 어느 등록 라이브러리에서 찾을지. 미지정 시 `u-icon`의 기본 URL 경로로
|
|
11
|
+
* 해석된다(`IconRegistry.register()`로 등록한 이름 있는 세트를 쓰려면 지정해야 함). */
|
|
12
|
+
lib?: string;
|
|
10
13
|
label?: string | DirectiveResult;
|
|
11
14
|
styles?: StyleMap<ElementParts>;
|
|
12
15
|
onClick?: (event?: Event) => void;
|
|
@@ -20,6 +23,8 @@ export declare class SidebarButton extends StyledElement<ElementParts> {
|
|
|
20
23
|
compact: boolean;
|
|
21
24
|
/** 기본 u-icon 경로의 아이콘 이름 */
|
|
22
25
|
icon?: string;
|
|
26
|
+
/** `icon`을 해석할 등록 라이브러리 이름 */
|
|
27
|
+
lib?: string;
|
|
23
28
|
/** 버튼 텍스트 라벨 */
|
|
24
29
|
label?: string | DirectiveResult;
|
|
25
30
|
render(): import('lit-html').TemplateResult<1>;
|
|
@@ -18,6 +18,7 @@ var c = class extends n {
|
|
|
18
18
|
return a`
|
|
19
19
|
<button part="base" ?compact=${this.compact}>
|
|
20
20
|
<u-icon part="icon"
|
|
21
|
+
.lib=${this.lib}
|
|
21
22
|
.name=${this.icon}
|
|
22
23
|
.fallback=${r}
|
|
23
24
|
></u-icon>
|
|
@@ -31,6 +32,6 @@ var c = class extends n {
|
|
|
31
32
|
t([s({
|
|
32
33
|
type: Boolean,
|
|
33
34
|
reflect: !0
|
|
34
|
-
}), e("design:type", Object)], c.prototype, "compact", void 0), t([s({ type: String }), e("design:type", String)], c.prototype, "icon", void 0), t([s({ type: String }), e("design:type", Object)], c.prototype, "label", void 0), c = t([o("u-sidebar-button")], c);
|
|
35
|
+
}), e("design:type", Object)], c.prototype, "compact", void 0), t([s({ type: String }), e("design:type", String)], c.prototype, "icon", void 0), t([s({ type: String }), e("design:type", String)], c.prototype, "lib", void 0), t([s({ type: String }), e("design:type", Object)], c.prototype, "label", void 0), c = t([o("u-sidebar-button")], c);
|
|
35
36
|
//#endregion
|
|
36
37
|
export { c as SidebarButton };
|
|
@@ -9,6 +9,7 @@ export interface SidebarGroupConfig extends SidebarPermissionGuard {
|
|
|
9
9
|
/** 기본 접힘 상태 */
|
|
10
10
|
collapsed?: boolean;
|
|
11
11
|
icon: string;
|
|
12
|
+
lib?: string;
|
|
12
13
|
label: string | DirectiveResult;
|
|
13
14
|
items: SidebarLinkConfig[];
|
|
14
15
|
styles?: StyleMap<ElementParts>;
|
|
@@ -26,6 +27,8 @@ export declare class SidebarGroup extends StyledElement<ElementParts> {
|
|
|
26
27
|
collapsed: boolean;
|
|
27
28
|
/** 네비게이션 아이템 데이터 */
|
|
28
29
|
icon?: string;
|
|
30
|
+
/** `icon`을 해석할 등록 라이브러리 이름 */
|
|
31
|
+
lib?: string;
|
|
29
32
|
/** 네비게이션 아이템 데이터 */
|
|
30
33
|
label?: string | DirectiveResult;
|
|
31
34
|
render(): import('lit-html').TemplateResult<1>;
|
|
@@ -30,6 +30,7 @@ var l = class extends n {
|
|
|
30
30
|
빠져 있었다.
|
|
31
31
|
-->
|
|
32
32
|
<u-icon class="icon" part="icon"
|
|
33
|
+
.lib=${this.lib}
|
|
33
34
|
.name=${this.icon}
|
|
34
35
|
.fallback=${r}
|
|
35
36
|
></u-icon>
|
|
@@ -59,6 +60,6 @@ t([c({
|
|
|
59
60
|
}), e("design:type", Boolean)], l.prototype, "selected", void 0), t([c({
|
|
60
61
|
type: Boolean,
|
|
61
62
|
reflect: !0
|
|
62
|
-
}), e("design:type", Boolean)], l.prototype, "collapsed", void 0), t([c({ type: String }), e("design:type", String)], l.prototype, "icon", void 0), t([c({ type: String }), e("design:type", Object)], l.prototype, "label", void 0), l = t([s("u-sidebar-group")], l);
|
|
63
|
+
}), e("design:type", Boolean)], l.prototype, "collapsed", void 0), t([c({ type: String }), e("design:type", String)], l.prototype, "icon", void 0), t([c({ type: String }), e("design:type", String)], l.prototype, "lib", void 0), t([c({ type: String }), e("design:type", Object)], l.prototype, "label", void 0), l = t([s("u-sidebar-group")], l);
|
|
63
64
|
//#endregion
|
|
64
65
|
export { l as SidebarGroup };
|
|
@@ -6,6 +6,7 @@ type ElementParts = 'host' | 'base' | 'icon' | 'label';
|
|
|
6
6
|
export interface SidebarLinkConfig extends SidebarPermissionGuard {
|
|
7
7
|
type: 'link';
|
|
8
8
|
icon?: string;
|
|
9
|
+
lib?: string;
|
|
9
10
|
label: string | DirectiveResult;
|
|
10
11
|
href: string;
|
|
11
12
|
pattern?: string | URLPattern;
|
|
@@ -42,6 +43,8 @@ export declare class SidebarLink extends StyledElement<ElementParts> {
|
|
|
42
43
|
compact: boolean;
|
|
43
44
|
/** 네비게이션 아이템 데이터 */
|
|
44
45
|
icon?: string;
|
|
46
|
+
/** `icon`을 해석할 등록 라이브러리 이름 */
|
|
47
|
+
lib?: string;
|
|
45
48
|
/** 네비게이션 아이템 데이터 */
|
|
46
49
|
label?: string | DirectiveResult;
|
|
47
50
|
/** 네비게이션 링크 */
|
|
@@ -23,6 +23,7 @@ var c = class extends n {
|
|
|
23
23
|
>
|
|
24
24
|
<div class="container" part="base" ?compact=${this.compact}>
|
|
25
25
|
<u-icon part="icon"
|
|
26
|
+
.lib=${this.lib}
|
|
26
27
|
.name=${this.icon}
|
|
27
28
|
.fallback=${r}
|
|
28
29
|
></u-icon>
|
|
@@ -37,6 +38,6 @@ var c = class extends n {
|
|
|
37
38
|
t([s({
|
|
38
39
|
type: Boolean,
|
|
39
40
|
reflect: !0
|
|
40
|
-
}), e("design:type", Object)], c.prototype, "selected", void 0), t([s({ type: Boolean }), e("design:type", Object)], c.prototype, "compact", void 0), t([s({ type: String }), e("design:type", String)], c.prototype, "icon", void 0), t([s({ type: String }), e("design:type", Object)], c.prototype, "label", void 0), t([s({ type: String }), e("design:type", String)], c.prototype, "href", void 0), t([s({ type: String }), e("design:type", Object)], c.prototype, "pattern", void 0), t([s({ type: String }), e("design:type", String)], c.prototype, "navigate", void 0), t([s({ type: String }), e("design:type", String)], c.prototype, "target", void 0), c = t([o("u-sidebar-link")], c);
|
|
41
|
+
}), e("design:type", Object)], c.prototype, "selected", void 0), t([s({ type: Boolean }), e("design:type", Object)], c.prototype, "compact", void 0), t([s({ type: String }), e("design:type", String)], c.prototype, "icon", void 0), t([s({ type: String }), e("design:type", String)], c.prototype, "lib", void 0), t([s({ type: String }), e("design:type", Object)], c.prototype, "label", void 0), t([s({ type: String }), e("design:type", String)], c.prototype, "href", void 0), t([s({ type: String }), e("design:type", Object)], c.prototype, "pattern", void 0), t([s({ type: String }), e("design:type", String)], c.prototype, "navigate", void 0), t([s({ type: String }), e("design:type", String)], c.prototype, "target", void 0), c = t([o("u-sidebar-link")], c);
|
|
41
42
|
//#endregion
|
|
42
43
|
export { c as SidebarLink };
|
|
@@ -46,9 +46,14 @@ var t = e`
|
|
|
46
46
|
|
|
47
47
|
u-icon {
|
|
48
48
|
flex-shrink: 0;
|
|
49
|
-
color: inherit;
|
|
49
|
+
color: var(--link-icon-color, inherit);
|
|
50
50
|
font-size: 20px;
|
|
51
51
|
}
|
|
52
|
+
/* Selected always wins over any consumer-supplied --link-icon-color — a
|
|
53
|
+
* high-contrast icon on the active background matters more than a brand tint. */
|
|
54
|
+
:host([selected]) u-icon {
|
|
55
|
+
color: var(--app-sidebar-active-fg, var(--u-txt-color-inverse, #FFFFFF));
|
|
56
|
+
}
|
|
52
57
|
|
|
53
58
|
/*
|
|
54
59
|
* ★내비 항목은 «대상의 짧은 이름» = label 단이다(용도 배정 — DL-157-4).
|
|
@@ -157,6 +157,7 @@ var g = class extends i {
|
|
|
157
157
|
<u-sidebar-button
|
|
158
158
|
?compact=${this.state === "slim"}
|
|
159
159
|
.icon="${e.icon}"
|
|
160
|
+
.lib="${e.lib}"
|
|
160
161
|
.label="${e.label}"
|
|
161
162
|
.styles="${e.styles}"
|
|
162
163
|
@click="${e.onClick}"
|
|
@@ -169,6 +170,7 @@ var g = class extends i {
|
|
|
169
170
|
?compact=${this.state === "slim"}
|
|
170
171
|
?selected=${t}
|
|
171
172
|
.icon="${e.icon}"
|
|
173
|
+
.lib="${e.lib}"
|
|
172
174
|
.label="${e.label}"
|
|
173
175
|
.href="${e.href}"
|
|
174
176
|
.pattern="${e.pattern}"
|
|
@@ -195,6 +197,7 @@ var g = class extends i {
|
|
|
195
197
|
?selected=${t}
|
|
196
198
|
?collapsed="${e.collapsed ?? !1}"
|
|
197
199
|
.icon="${e.icon}"
|
|
200
|
+
.lib="${e.lib}"
|
|
198
201
|
.label="${e.label}"
|
|
199
202
|
.styles="${e.styles}">
|
|
200
203
|
${p(e.items, (e, t) => t, (e) => this.renderItem(e))}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iyulab/modern-app",
|
|
3
3
|
"description": "web-framework by iyulab based on lit-element",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.14.0",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"iyulab",
|
|
7
7
|
"web-framework",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"typecheck": "tsc --noEmit"
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@iyulab/components": "^1.
|
|
56
|
+
"@iyulab/components": "^1.27.0",
|
|
57
57
|
"@iyulab/router": "^0.11.0",
|
|
58
58
|
"i18next": "^26.3.6",
|
|
59
59
|
"lit": "^3.3.3"
|
|
@@ -34,10 +34,16 @@ and those are different states of the business. So the component owns the rule.
|
|
|
34
34
|
| `value` | `unknown` | — | | Value; property only (`attribute: false`) |
|
|
35
35
|
| `blank` | `string` | `'—'` | | Placeholder for null/undefined/empty — **not** for `0` or `false` |
|
|
36
36
|
| `numeric` | `boolean` | `false` | | Right-align with tabular figures so digits line up vertically |
|
|
37
|
+
| `format` | `'number'\|'currency'\|'date'` | — | | Renders `value` through `@iyulab/components`' `formatNumber`/`formatCurrency`/`formatDate`; unset falls back to plain `String(value)` |
|
|
38
|
+
| `currency` | `string` | — | | Currency code for `format="currency"` (e.g. `'KRW'`); omitted degrades to plain number formatting, does not throw |
|
|
37
39
|
|
|
38
40
|
⚠ `numeric` earns its keep in **tables**, where columns of figures are compared by eye. On a
|
|
39
41
|
lone field it just pushes the value away from its label.
|
|
40
42
|
|
|
43
|
+
```html
|
|
44
|
+
<u-info-field label="Total" format="currency" currency="KRW" .value=${order.total}></u-info-field>
|
|
45
|
+
```
|
|
46
|
+
|
|
41
47
|
## CSS Parts
|
|
42
48
|
|
|
43
49
|
| Part | Description |
|
|
@@ -39,6 +39,7 @@ interface SidebarLinkConfig {
|
|
|
39
39
|
label: string | DirectiveResult;
|
|
40
40
|
href: string;
|
|
41
41
|
icon?: string;
|
|
42
|
+
lib?: string;
|
|
42
43
|
/** Override the URL matching pattern. Accepts a string or URLPattern. */
|
|
43
44
|
pattern?: string | URLPattern;
|
|
44
45
|
/** Let the browser navigate instead of the router. For same-origin, non-SPA paths. */
|
|
@@ -81,6 +82,7 @@ Collapsible group that contains links.
|
|
|
81
82
|
interface SidebarGroupConfig {
|
|
82
83
|
type: 'group';
|
|
83
84
|
icon: string;
|
|
85
|
+
lib?: string;
|
|
84
86
|
label: string | DirectiveResult;
|
|
85
87
|
items: SidebarLinkConfig[];
|
|
86
88
|
/** Start collapsed. Default: true */
|
|
@@ -143,6 +145,7 @@ Action button — triggers a callback instead of navigating.
|
|
|
143
145
|
interface SidebarButtonConfig {
|
|
144
146
|
type: 'button';
|
|
145
147
|
icon?: string;
|
|
148
|
+
lib?: string;
|
|
146
149
|
label: string | DirectiveResult;
|
|
147
150
|
onClick: () => void;
|
|
148
151
|
styles?: StyleMap<string>;
|