@iyulab/components 1.23.0 โ†’ 1.24.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 CHANGED
@@ -1,5 +1,67 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.24.0] - 2026-08-04
4
+
5
+ ### Added
6
+
7
+ - ๐Ÿ”ด**`u-text` โ€” ์˜๋ฏธ ํƒ€์ดํฌ๊ทธ๋ž˜ํ”ผ ์Šค์ผ€์ผ(7๋‹จ)์„ ๋งˆํฌ์—…์—์„œ ์“ฐ๋Š” ์ž๋ฆฌ.**
8
+ ์‹œํŠธ๋Š” `1.21.0` ๋ถ€ํ„ฐ ๋‹จ๋งˆ๋‹ค **ํฌ๊ธฐยท๊ตต๊ธฐยทํ–‰๊ฐ„ยท์ž๊ฐ„** ๋„ค ๊ฐ’์„ ๊ฐ–๊ณ  ์žˆ์—ˆ์ง€๋งŒ **๊ทธ ๋‹จ์„
9
+ ์ ์šฉํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์—†์—ˆ๋‹ค** โ€” ์†Œ๋น„์ž๊ฐ€ ์Šค์ผ€์ผ์„ ์“ฐ๋ ค๋ฉด ์ž๊ธฐ CSS ์—์„œ ํ† ํฐ์„ ์ง์ ‘
10
+ ์ฐธ์กฐํ•ด์•ผ ํ–ˆ๊ณ , ๊ทธ๋Ÿฌ๋ฉด ยซ์ปดํฌ๋„ŒํŠธ๋งŒ์œผ๋กœ ํ™”๋ฉด์„ ์ง“๋Š”๋‹คยป๊ฐ€ ๊ทธ ์ž๋ฆฌ์—์„œ ๊นจ์กŒ๋‹ค.
11
+ โ‡’ ์šฐ๋ฆฌ๊ฐ€ ์ค€ ๊ฒƒ์€ **๊ฐ’**์ด๊ณ  ํ•„์š”ํ–ˆ๋˜ ๊ฒƒ์€ **์ž๋ฆฌ**๋‹ค.
12
+
13
+ ```html
14
+ <u-text level="1" variant="display">๋ฌธ์„œ ์ œ๋ชฉ</u-text>
15
+ <u-text variant="subtitle" tone="weak">ํ•œ ์ค„ ์„ค๋ช…</u-text>
16
+ <u-text>๋ณธ๋ฌธ</u-text>
17
+ <u-text variant="caption" tone="weak">๋ณด์กฐ ๋ฌธ๊ตฌ</u-text>
18
+ ```
19
+
20
+ โ˜…**์‹œ๊ฐ ์ถ•(`variant`)๊ณผ ์˜๋ฏธ ์ถ•(`level`)์ด ๋…๋ฆฝ**์ด๋‹ค โ€” `level` ์„ ์ฃผ๋ฉด ์„€๋„ ๋ฃจํŠธ์— ์‹ค์ œ
21
+ `<h1>`~`<h6>` ์„ ๋ Œ๋”ํ•ด heading ์œผ๋กœ ์ฝํžˆ๊ณ (์Šฌ๋กฏ ํ…์ŠคํŠธ๊ฐ€ ์ ‘๊ทผ๊ฐ€๋Šฅ ์ด๋ฆ„), ์ฃผ์ง€ ์•Š์œผ๋ฉด
22
+ `<p>` ๋‹ค. ๊ทธ๋ž˜์„œ *"ํŽ˜์ด์ง€์˜ ๋‘ ๋ฒˆ์งธ ์ œ๋ชฉ์ด ์‹œ๊ฐ์ ์œผ๋กœ ๊ฐ€์žฅ ํฐ"* ๋ฐฐ์น˜๊ฐ€ ๋งˆํฌ์—…์„
23
+ ๊ฑฐ์ง“๋ง์‹œํ‚ค์ง€ ์•Š๊ณ  ํ‘œํ˜„๋œ๋‹ค.
24
+
25
+ โš **`tone` ์€ ์ค‘๋ฆฝ ๊ฐ•์กฐ ์ถ•์ด๋‹ค**(`default`ยท`weak`ยท`strong`ยท`inverse`) โ€” ์—ญํ• ์ƒ‰์ด
26
+ ์•„๋‹ˆ๋‹ค. ์†Œ๋น„ ํ™”๋ฉด ์‹ค์ธก์—์„œ ๋‚˜์˜จ ์ƒ‰ ๋‹ค์„ฏ ์ค‘ ์…‹์ด ์ด ์ถ•์ด์—ˆ๊ณ  ๋‚˜๋จธ์ง€ ๋‘˜์€ **๋งํฌ**์™€
27
+ **์ฝœ์•„์›ƒ ๋ฐ•์Šค**๋ผ ์ด ์ปดํฌ๋„ŒํŠธ์˜ ์ถ•์ด ์•„๋‹ˆ์—ˆ๋‹ค.
28
+
29
+ โš **๊ฐ’์„ ์ƒˆ๋กœ ์ •์˜ํ•˜์ง€ ์•Š๋Š”๋‹ค** โ€” 7๋‹จ ร— 4์†์„ฑ์„ ์‹œํŠธ์—์„œ ์ฝ๊ธฐ๋งŒ ํ•œ๋‹ค. ํšŒ๊ท€ 12๊ฑด์ด
30
+ *"์–ด๋–ค ํฌ๊ธฐ์ธ๊ฐ€"* ๊ฐ€ ์•„๋‹ˆ๋ผ ***"์‹œํŠธ๊ฐ€ ๋งํ•œ ๊ทธ ๊ฐ’์„ ์“ฐ๋Š”๊ฐ€"*** ๋ฅผ ์žฐ๋‹ค.
31
+ ๊ฐ™์€ ์ด์œ ๋กœ `overline` ์— `text-transform: uppercase` ๋ฅผ **๋ถ™์ด์ง€ ์•Š์•˜๋‹ค** โ€” ๊ด€์Šต์ด๊ธด ํ•˜๋‚˜
32
+ ์†Œ๋น„์ž๊ฐ€ ์“ด ๊ธ€์ž๋ฅผ ๋ฐ”๊พธ๊ณ , CJK ์—๋Š” ํšจ๊ณผ๊ฐ€ ์—†์–ด **๊ฐ™์€ ๋‹จ์ด ์–ธ์–ด์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ๋ณด์ธ๋‹ค.**
33
+
34
+ ### Fixed
35
+
36
+ - ๐Ÿ”ด**`u-field` ์•ˆ์˜ ์ปจํŠธ๋กค์ด ํ•„๋“œ ํญ์„ ์ฑ„์šฐ์ง€ ์•Š์•„ ํผ ๊ฒฉ์ž๊ฐ€ ์–ด๊ธ‹๋‚ฌ๋‹ค.** ์‹ค์ธก: ๊ฐ™์€ 231px
37
+ ์นธ ์•ˆ์—์„œ `u-input` 202 ยท `u-select` 71/92/108 ยท `u-textarea` 168 โ€” **์˜ค๋ฅธ์ชฝ ๋์ด ๋‹ค์„ฏ
38
+ ๊ตฐ๋ฐ์—์„œ ๋‹ค ๋‹ฌ๋ž๋‹ค.** ์ปจํŠธ๋กค ์ž์‹ ์˜ ๊ธฐ๋ณธ๊ฐ’(`inline-block`)์€ ์˜ณ์ง€๋งŒ, `u-field` ๋กœ ๊ฐ์‹ผ
39
+ ์ˆœ๊ฐ„ ๊ทธ๊ฒƒ์€ **ํผ์˜ ํ•œ ์นธ**์ด๋‹ค โ‡’ ๋ผ๋ฒจยท์„ค๋ช…ยท๊ฒ€์ฆ ๋ฌธ๊ตฌ์˜ ๋ฐฐ์น˜๋ฅผ ์ฑ…์ž„์ง€๋Š” ์ด ์ปดํฌ๋„ŒํŠธ๊ฐ€
40
+ ํญ๋„ ํ•จ๊ป˜ ์ •ํ•œ๋‹ค(`::slotted(*) { width: 100% }`).
41
+ โš ์†Œ๋น„์ž๊ฐ€ ์ธ๋ผ์ธ `style` ๋กœ ํญ์„ ์ฃผ๋ฉด ๊ทธ์ชฝ์ด ์ด๊ธด๋‹ค.
42
+
43
+ ### Added
44
+
45
+ - **`u-icon[fallback]`** โ€” ์ด๋ฆ„ยทURL ์ด ํ•ด์„๋˜์ง€ ์•Š์„ ๋•Œ ๋Œ€์‹  ๊ทธ๋ฆด SVG ์›๋ฌธ.
46
+ ยซ์•„์ด์ฝ˜์ด ์•ˆ ๋ณด์ธ๋‹คยป๊ฐ€ **ยซ๋ˆ„๋ฅผ ๊ฒƒ์ด ์—†๋‹คยป** ๊ฐ€ ๋˜๋Š” ์ž๋ฆฌ๊ฐ€ ์žˆ๋‹ค(์ ‘ํžŒ ์‚ฌ์ด๋“œ๋ฐ”์˜ ๋ฉ”๋‰ด ํ•ญ๋ชฉ).
47
+ ํ•ด์„ ์‹คํŒจ๋Š” ์ด๋ฆ„ ๋ฏธ์ง€์ • ยท 404 ยท SVG ํŒŒ์‹ฑ ์‹คํŒจ๋ฅผ **๋ชจ๋‘** ํฌํ•จํ•œ๋‹ค.
48
+
49
+ ### Documentation
50
+
51
+ - ๐Ÿ”ด**`Theme.accent(seed)` ๊ฐ€ `primary` ์—ญํ•  ํ† ํฐ **7์ข… ์ค‘ 6์ข…**๋งŒ ์„ธํŒ…ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ๋ช…์‹œํ–ˆ๋‹ค.**
52
+ `--u-primary-bg-color`(`u-tag` ์˜ `--tag-hue-surface` ๊ฐ€ ์ฝ๋Š” ยซ๊ธ€์ž๋ฅผ ์–น๋Š” ์˜…์€ ๋ฉดยป)๋Š”
53
+ ์‹œํŠธ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ๋‚จ์œผ๋ฏ€๋กœ, **์‹œ๋“œ๋งŒ ๋„ฃ์œผ๋ฉด ํƒœ๊ทธยท์„ ํƒ๋œ ํ–‰ ๊ฐ™์€ ์˜…์€ ๋ฉด์ด ํŒŒ๋ž‘์œผ๋กœ ๋‚จ๋Š”๋‹ค.**
54
+ ์‹ค์ธก๋œ ์ฆ์ƒ์ด *"๋ฒ„ํŠผ์€ ๋ธŒ๋žœ๋“œ์ธ๋ฐ ์„ ํƒ๋œ ํ‘œ ํ–‰์€ ํŒŒ๋ž‘"* ์ด๋‹ค.
55
+ โ‡’ `usage.md` ๋ธŒ๋žœ๋“œ ์ ˆ์— **7์ข… ํ‘œ**์™€ ํ•œ ์ค„ ํ•ด๋ฒ•์„, `Theme.accent` JSDoc ์— ๊ฐ™์€ ๋‚ด์šฉ์„ ์ ์—ˆ๋‹ค.
56
+
57
+ โš **ํŒŒ์ƒ์„ ๋ถ™์ด์ง€ ์•Š์€ ์ด์œ **: ์ด ํ† ํฐ์€ `info`ยท`success`ยท`danger`ยท`warning` ๊ณผ ํ•œ ์„ธํŠธ๋กœ
58
+ **5๊ณ„์—ด ร— 2ํ…Œ๋งˆ = 10๊ฐœ ๊ฐ’์ด ์†์œผ๋กœ ์ง์ง€์–ด์ ธ** ์žˆ๊ณ , ๋‘ ํ…Œ๋งˆ๊ฐ€ ๊ฐ™์€ ๊ณ„์•ฝ์„ ์“ฐ์ง€ ์•Š๋Š”๋‹ค
59
+ (๋ฐ”ํƒ• ๋Œ€๋น„๋น„ ์‹ค์ธก โ€” ๋ผ์ดํŠธ **1.142** ยท ๋‹คํฌ **1.030**). ๋„์ถœ์‹์œผ๋กœ ๋ฐ”๊พธ๋Š” ๊ฒƒ์€ ํŒ”๋ ˆํŠธ
60
+ ๊ฐ’ ๊ฒฐ์ •์ด๋ผ ๋ณ„๋„ ํŒ๋‹จ์ด ํ•„์š”ํ•˜๋‹ค.
61
+
62
+ ๋ธŒ๋ผ์šฐ์ € ํšŒ๊ท€ 2๊ฑด์ด ์ด ๋ฌธ์„œ๊ฐ€ ์ฐธ์ธ์ง€ ์žฐ๋‹ค โ€” **๊ฒฐ์†์„ ๊ณ ์ •ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ**, ๋‚˜์ค‘์— ํŒŒ์ƒ์ด
63
+ ๋ถ™์œผ๋ฉด ๊ทธ ํ…Œ์ŠคํŠธ๊ฐ€ ๋’ค์ง‘ํžˆ๋ฉด์„œ ๋ฌธ์„œ๋„ ๊ณ ์น˜๋ผ๊ณ  ์•Œ๋ฆฐ๋‹ค.
64
+
3
65
  ## [1.23.0] - 2026-08-04
4
66
 
5
67
  ### Added
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) [year] [fullname]
3
+ Copyright (c) 2024 iyulab
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -76,7 +76,7 @@ npx skills add ./node_modules/@iyulab/components
76
76
 
77
77
  **Navigation** โ€” `u-menu`, `u-menu-item`, `u-tab-panel`, `u-breadcrumb`, `u-breadcrumb-item`, `u-tree`, `u-tree-item`
78
78
 
79
- **Layout & Display** โ€” `u-avatar`, `u-card`, `u-carousel`, `u-divider`, `u-icon`, `u-panel`, `u-split-panel`, `u-tag`
79
+ **Layout & Display** โ€” `u-avatar`, `u-card`, `u-carousel`, `u-divider`, `u-icon`, `u-panel`, `u-split-panel`, `u-tag`, `u-text`
80
80
 
81
81
  ## Theming
82
82
 
@@ -15,6 +15,21 @@ var styles = css`
15
15
  color: var(--u-danger-color-strong, #C62828);
16
16
  }
17
17
 
18
+ /* ๐Ÿ”ด**๋ผ๋ฒจ์„ ๋‹จ ์ปจํŠธ๋กค์€ ํ•„๋“œ ํญ์„ ์ฑ„์šด๋‹ค.**
19
+ ์ปจํŠธ๋กค ์ž์‹ ์˜ ๊ธฐ๋ณธ๊ฐ’์€ inline-block(์ž๊ธฐ ๋‚ด์šฉ๋งŒํผ)์ด ์˜ณ๋‹ค โ€” ๋ฌธ์žฅ ์•ˆ์— ๋†“์ด๋Š” ๊ฒฝ์šฐ๊ฐ€
20
+ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ u-field ๋กœ ๊ฐ์‹ผ ์ˆœ๊ฐ„ ๊ทธ๊ฒƒ์€ **ํผ์˜ ํ•œ ์นธ**์ด๊ณ , ์นธ๋งˆ๋‹ค ์ปจํŠธ๋กค์ด
21
+ ์ œ๊ฐ๊ฐ์˜ ํญ์„ ๊ฐ€์ง€๋ฉด ๊ฒฉ์ž๊ฐ€ ๋„ˆ๋œ๋„ˆ๋œํ•ด์ง„๋‹ค. ์‹ค์ธก: ๊ฐ™์€ 231px ์นธ ์•ˆ์—์„œ input 202 ยท
22
+ select 71/92/108 ยท textarea 168 โ€” **์˜ค๋ฅธ์ชฝ ๋์ด ๋‹ค์„ฏ ๊ตฐ๋ฐ์—์„œ ๋‹ค ๋‹ฌ๋ž๋‹ค.**
23
+ โ‡’ ๋ผ๋ฒจยท์„ค๋ช…ยท๊ฒ€์ฆ ๋ฌธ๊ตฌ์˜ ๋ฐฐ์น˜๋ฅผ ์ฑ…์ž„์ง€๋Š” ์ด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํญ๋„ ํ•จ๊ป˜ ์ •ํ•œ๋‹ค.
24
+
25
+ โš ์†Œ๋น„์ž๊ฐ€ ์ธ๋ผ์ธ style ๋กœ ํญ์„ ์ฃผ๋ฉด ๊ทธ์ชฝ์ด ์ด๊ธด๋‹ค(์ธ๋ผ์ธ > ::slotted).
26
+ โš ์ด ์ฃผ์„์— ๋ฐฑํ‹ฑ์„ ์“ฐ์ง€ ๋ง ๊ฒƒ โ€” css ํƒœ๊ทธ๋“œ ํ…œํ”Œ๋ฆฟ์„ ๊ทธ ์ž๋ฆฌ์—์„œ ๋๋‚ธ๋‹ค(์ด ํŒŒ์ผ์ด ์‹ค์ œ๋กœ
27
+ ๊ทธ๋ ‡๊ฒŒ ๊นจ์กŒ๊ณ , cycle-217 ์ด ๋งŒ๋“  ํƒ€์ž… ๊ฒŒ์ดํŠธ๊ฐ€ ์žก์•˜๋‹ค). */
28
+ ::slotted(*) {
29
+ width: 100%;
30
+ box-sizing: border-box;
31
+ }
32
+
18
33
  .header {
19
34
  display: flex;
20
35
  flex-direction: row;
@@ -1,4 +1,3 @@
1
- import { nothing } from 'lit';
2
1
  import { UElement } from '../UElement.js';
3
2
  export type IconLibrary = (string & {}) | "internal" | "tabler" | "heroicons" | "lucide" | "bootstrap";
4
3
  /**
@@ -14,9 +13,23 @@ export declare class UIcon extends UElement {
14
13
  lib?: IconLibrary;
15
14
  /** ์‚ฌ์šฉํ•  ์•„์ด์ฝ˜ ์ด๋ฆ„์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. */
16
15
  name?: string;
17
- render(): import('lit-html/directive.js').DirectiveResult<{
18
- new (_partInfo: import('lit-html/directive.js').PartInfo): import('lit-html/directives/until.js').UntilDirective<typeof nothing | Promise<import('lit-html/directive.js').DirectiveResult<typeof import('lit-html/directives/unsafe-html.js').UnsafeHTMLDirective>>>;
19
- }>;
16
+ /**
17
+ * ์ด๋ฆ„ยทURL ์ด **ํ•ด์„๋˜์ง€ ์•Š์„ ๋•Œ** ๋Œ€์‹  ๊ทธ๋ฆด SVG ์›๋ฌธ.
18
+ *
19
+ * โ˜…**ยซ์•„์ด์ฝ˜์ด ์•ˆ ๋ณด์ธ๋‹คยป๊ฐ€ ยซ์ž๋ฆฌ ์ž์ฒด๊ฐ€ ์‚ฌ๋ผ์ง„๋‹คยป๊ฐ€ ๋˜๋Š” ๊ณณ์ด ์žˆ๋‹ค.** ์‚ฌ์ด๋“œ๋ฐ”๊ฐ€ ์ ‘ํžˆ๋ฉด
20
+ * ๋ผ๋ฒจ์ด ์ˆจ๊ณ  ์•„์ด์ฝ˜๋งŒ ๋‚จ๋Š”๋ฐ, ๊ทธ ์•„์ด์ฝ˜์ด ํ•ด์„์— ์‹คํŒจํ•˜๋ฉด ๊ทธ ๋ฉ”๋‰ด๋Š” **๋ˆ„๋ฅผ ๊ฒƒ์ด ์—†๋Š”
21
+ * ๋นˆ ์ค„**์ด ๋œ๋‹ค โ€” ์ด๋ฆ„์ด ์ž˜๋ชป๋๋Š”์ง€, ํŒŒ์ผ์ด ์—†๋Š”์ง€, ์•„์ด์ฝ˜์„ ์•ˆ ์ค€ ๊ฒƒ์ธ์ง€ ํ™”๋ฉด์—์„œ
22
+ * ๊ตฌ๋ถ„๋˜์ง€ ์•Š๊ณ  **ํƒ์ƒ‰ ์ˆ˜๋‹จ์ด ํ†ต์งธ๋กœ ์‚ฌ๋ผ์ง„๋‹ค.**
23
+ *
24
+ * โ‡’ ๊ทธ๋Ÿฐ ์ž๋ฆฌ๋Š” ยซ์—†์œผ๋ฉด ์•ˆ ๊ทธ๋ฆฐ๋‹คยป๊ฐ€ ์•„๋‹ˆ๋ผ **ยซ์—†์œผ๋ฉด ๋Œ€์‹  ๊ทธ๋ฆฐ๋‹คยป** ์—ฌ์•ผ ํ•œ๋‹ค.
25
+ * ํ•ด์„ ์‹คํŒจ๋Š” `name` ๋ฏธ์ง€์ • ยท ํŒŒ์ผ ์—†์Œ(404) ยท SVG ํŒŒ์‹ฑ ์‹คํŒจ๋ฅผ **๋ชจ๋‘** ํฌํ•จํ•œ๋‹ค.
26
+ *
27
+ * โš ์†Œ๋น„์ž๊ฐ€ ์ฃผ๋Š” ๊ฐ’์€ `sanitize()` ๋ฅผ ๊ฑฐ์นœ๋‹ค(`name` ๊ฒฝ๋กœ์™€ ๊ฐ™์€ ์ฒ˜๋ฆฌ).
28
+ */
29
+ fallback?: string;
30
+ render(): import('lit-html/directive.js').DirectiveResult<typeof import('lit-html/directives/unsafe-html.js').UnsafeHTMLDirective>;
31
+ /** ํ•ด์„ ๊ฒฐ๊ณผ๊ฐ€ ์—†์œผ๋ฉด `fallback` ์œผ๋กœ ๋Œ€์‹ ํ•œ๋‹ค. ๋‘˜ ๋‹ค ์—†์„ ๋•Œ๋งŒ ์•„๋ฌด๊ฒƒ๋„ ๊ทธ๋ฆฌ์ง€ ์•Š๋Š”๋‹ค. */
32
+ private paint;
20
33
  private resolve;
21
34
  private sanitize;
22
35
  }
@@ -14,13 +14,15 @@ var UIcon = class UIcon extends UElement {
14
14
  }
15
15
  render() {
16
16
  if (this.src) return until(IconRegistry.resolveUrl(this.src).then((html) => {
17
- const sanitized = this.sanitize(html);
18
- return sanitized ? unsafeHTML(sanitized) : nothing;
17
+ return this.paint(this.sanitize(html));
19
18
  }), nothing);
20
- if (this.name) return until(this.resolve(this.name).then((html) => {
21
- return html ? unsafeHTML(html) : nothing;
22
- }), nothing);
23
- return nothing;
19
+ if (this.name) return until(this.resolve(this.name).then((html) => this.paint(html)), nothing);
20
+ return this.paint(void 0);
21
+ }
22
+ /** ํ•ด์„ ๊ฒฐ๊ณผ๊ฐ€ ์—†์œผ๋ฉด `fallback` ์œผ๋กœ ๋Œ€์‹ ํ•œ๋‹ค. ๋‘˜ ๋‹ค ์—†์„ ๋•Œ๋งŒ ์•„๋ฌด๊ฒƒ๋„ ๊ทธ๋ฆฌ์ง€ ์•Š๋Š”๋‹ค. */
23
+ paint(html) {
24
+ const resolved = html ?? this.sanitize(this.fallback);
25
+ return resolved ? unsafeHTML(resolved) : nothing;
24
26
  }
25
27
  async resolve(name) {
26
28
  let html = void 0;
@@ -50,6 +52,7 @@ var UIcon = class UIcon extends UElement {
50
52
  __decorate([property({ type: String }), __decorateMetadata("design:type", String)], UIcon.prototype, "src", void 0);
51
53
  __decorate([property({ type: String }), __decorateMetadata("design:type", Object)], UIcon.prototype, "lib", void 0);
52
54
  __decorate([property({ type: String }), __decorateMetadata("design:type", String)], UIcon.prototype, "name", void 0);
55
+ __decorate([property({ type: String }), __decorateMetadata("design:type", String)], UIcon.prototype, "fallback", void 0);
53
56
  UIcon = __decorate([customElement("u-icon")], UIcon);
54
57
  //#endregion
55
58
  export { UIcon };
@@ -0,0 +1,38 @@
1
+ import { UElement } from '../UElement.js';
2
+ export type TextVariant = "display" | "title" | "subtitle" | "body" | "label" | "caption" | "overline";
3
+ /** ์ค‘๋ฆฝ ๊ฐ•์กฐ ์ถ•. **์—ญํ• ์ƒ‰์ด ์•„๋‹ˆ๋‹ค** โ€” ์—ญํ• ์ƒ‰์ด ํ•„์š”ํ•˜๋ฉด ๊ทธ๊ฒƒ์€ ๋ณ„๋„ ์ถ•์ด๋‹ค. */
4
+ export type TextTone = "default" | "weak" | "strong" | "inverse";
5
+ /** ์ œ๋ชฉ ๋‹จ๊ณ„. ๊ฐ’์ด ์žˆ์œผ๋ฉด heading ์œผ๋กœ ์ฝํžŒ๋‹ค. */
6
+ export type TextLevel = 1 | 2 | 3 | 4 | 5 | 6;
7
+ /**
8
+ * ์˜๋ฏธ ํƒ€์ดํฌ๊ทธ๋ž˜ํ”ผ ์Šค์ผ€์ผ(7๋‹จ)์„ ๋งˆํฌ์—…์—์„œ ์“ฐ๋Š” ์ž๋ฆฌ์ž…๋‹ˆ๋‹ค.
9
+ *
10
+ * ์‹œํŠธ๋Š” ๋‹จ๋งˆ๋‹ค **ํฌ๊ธฐยท๊ตต๊ธฐยทํ–‰๊ฐ„ยท์ž๊ฐ„** ๋„ค ๊ฐ’์„ ๊ฐ–๊ณ  ์žˆ์œผ๋‚˜, ๊ทธ ๋‹จ์„ *์ ์šฉํ•˜๋Š”* ๊ฒƒ์ด
11
+ * ์—†์–ด ์†Œ๋น„์ž๋Š” ์ž๊ธฐ CSS ์—์„œ ํƒ€์ดํฌ ํ† ํฐ์„ ์ง์ ‘ ์ฐธ์กฐํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค.
12
+ * ์ด ์ปดํฌ๋„ŒํŠธ๋Š” ๊ทธ ์ž๋ฆฌ๋ฅผ ๋Œ€์‹ ํ•˜๋ฉฐ, **๊ฐ’์„ ์ƒˆ๋กœ ์ •์˜ํ•˜์ง€ ์•Š๊ณ  ํ† ํฐ๋งŒ ์ฝ์Šต๋‹ˆ๋‹ค.**
13
+ *
14
+ * `level` ์„ ์ฃผ๋ฉด ์„€๋„ ๋ฃจํŠธ์— ์‹ค์ œ `<h1>`~`<h6>` ์„ ๋ Œ๋”ํ•˜๋ฏ€๋กœ heading ์œผ๋กœ ์ฝํž™๋‹ˆ๋‹ค
15
+ * (์Šฌ๋กฏ ํ…์ŠคํŠธ๊ฐ€ ์ ‘๊ทผ๊ฐ€๋Šฅ ์ด๋ฆ„์ด ๋ฉ๋‹ˆ๋‹ค). ์ฃผ์ง€ ์•Š์œผ๋ฉด `<p>` ์ž…๋‹ˆ๋‹ค.
16
+ *
17
+ * โš  ์‹œ๊ฐ ์ถ•(`variant`)๊ณผ ์˜๋ฏธ ์ถ•(`level`)์€ **๋…๋ฆฝ**์ž…๋‹ˆ๋‹ค โ€” ํŽ˜์ด์ง€์˜ ๋‘ ๋ฒˆ์งธ ์ œ๋ชฉ์ด
18
+ * ์‹œ๊ฐ์ ์œผ๋กœ ๊ฐ€์žฅ ํด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(`level="2" variant="display"`).
19
+ *
20
+ * @slot - ํ…์ŠคํŠธ ๋‚ด์šฉ
21
+ *
22
+ * @csspart base - ๋ Œ๋”๋œ `<p>` ๋˜๋Š” `<h1>`~`<h6>` ์š”์†Œ
23
+ */
24
+ export declare class UText extends UElement {
25
+ static styles: import('lit').CSSResultGroup[];
26
+ /** ์˜๋ฏธ ํƒ€์ดํฌ๊ทธ๋ž˜ํ”ผ ๋‹จ๊ณ„ */
27
+ variant: TextVariant;
28
+ /** ์ค‘๋ฆฝ ๊ฐ•์กฐ ์ถ• (์—ญํ• ์ƒ‰์ด ์•„๋‹ˆ๋‹ค) */
29
+ tone: TextTone;
30
+ /** ์ œ๋ชฉ ๋‹จ๊ณ„. ์ง€์ •ํ•˜๋ฉด heading ์š”์†Œ๋กœ ๋ Œ๋”๋œ๋‹ค */
31
+ level?: TextLevel;
32
+ protected render(): import('lit-html').TemplateResult;
33
+ }
34
+ declare global {
35
+ interface HTMLElementTagNameMap {
36
+ 'u-text': UText;
37
+ }
38
+ }
@@ -0,0 +1,45 @@
1
+ import { UElement } from "../UElement.js";
2
+ import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.142.0/helpers/esm/decorateMetadata.js";
3
+ import __decorate from "../../_virtual/_@oxc-project_runtime@0.142.0/helpers/esm/decorate.js";
4
+ import { styles } from "./UText.styles.js";
5
+ import { customElement, property } from "lit/decorators.js";
6
+ import { html, literal } from "lit/static-html.js";
7
+ //#region src/components/text/UText.ts
8
+ var PARAGRAPH = literal`p`;
9
+ var HEADINGS = {
10
+ 1: literal`h1`,
11
+ 2: literal`h2`,
12
+ 3: literal`h3`,
13
+ 4: literal`h4`,
14
+ 5: literal`h5`,
15
+ 6: literal`h6`
16
+ };
17
+ var UText = class UText extends UElement {
18
+ constructor(..._args) {
19
+ super(..._args);
20
+ this.variant = "body";
21
+ this.tone = "default";
22
+ }
23
+ static {
24
+ this.styles = [super.styles, styles];
25
+ }
26
+ render() {
27
+ const tag = this.level && HEADINGS[this.level] ? HEADINGS[this.level] : PARAGRAPH;
28
+ return html`<${tag} class="text" part="base"><slot></slot></${tag}>`;
29
+ }
30
+ };
31
+ __decorate([property({
32
+ type: String,
33
+ reflect: true
34
+ }), __decorateMetadata("design:type", Object)], UText.prototype, "variant", void 0);
35
+ __decorate([property({
36
+ type: String,
37
+ reflect: true
38
+ }), __decorateMetadata("design:type", Object)], UText.prototype, "tone", void 0);
39
+ __decorate([property({
40
+ type: Number,
41
+ reflect: true
42
+ }), __decorateMetadata("design:type", Object)], UText.prototype, "level", void 0);
43
+ UText = __decorate([customElement("u-text")], UText);
44
+ //#endregion
45
+ export { UText };
@@ -0,0 +1 @@
1
+ export declare const styles: import('lit').CSSResult;
@@ -0,0 +1,91 @@
1
+ import { css } from "lit";
2
+ //#region src/components/text/UText.styles.ts
3
+ var styles = css`
4
+ :host {
5
+ display: block;
6
+ color: var(--u-txt-color, #212121);
7
+ }
8
+
9
+ /*
10
+ * ๊ธฐ๋ณธ์€ body ๋‹ค. :host([variant="body"]) ๊ทœ์น™์„ ๋”ฐ๋กœ ๋‘์ง€ ์•Š๋Š” ์ด์œ ๋Š”
11
+ * ๊ฐ’์ด ๊ฐ™๊ธฐ ๋•Œ๋ฌธ์ด๋ฉฐ, ๋ถ€์ˆ˜ ํšจ๊ณผ๋กœ **์•Œ ์ˆ˜ ์—†๋Š” variant ๊ฐ€ body ๋กœ ํ๋ฅธ๋‹ค**
12
+ * (์กฐ์šฉํžˆ ํฐํŠธ๊ฐ€ ์‚ฌ๋ผ์ง€๋Š” ๊ฒƒ๋ณด๋‹ค ๋‚ซ๋‹ค).
13
+ */
14
+ .text {
15
+ margin: 0;
16
+ font-family: inherit;
17
+ font-size: var(--u-text-body-size, 14px);
18
+ font-weight: var(--u-text-body-weight, 400);
19
+ line-height: var(--u-text-body-leading, 1.6);
20
+ letter-spacing: var(--u-text-body-tracking, 0);
21
+ }
22
+
23
+ :host([variant="display"]) .text {
24
+ font-size: var(--u-text-display-size, 26px);
25
+ font-weight: var(--u-text-display-weight, 700);
26
+ line-height: var(--u-text-display-leading, 1.4);
27
+ letter-spacing: var(--u-text-display-tracking, -0.02em);
28
+ }
29
+
30
+ :host([variant="title"]) .text {
31
+ font-size: var(--u-text-title-size, 20px);
32
+ font-weight: var(--u-text-title-weight, 700);
33
+ line-height: var(--u-text-title-leading, 1.45);
34
+ letter-spacing: var(--u-text-title-tracking, -0.01em);
35
+ }
36
+
37
+ :host([variant="subtitle"]) .text {
38
+ font-size: var(--u-text-subtitle-size, 16px);
39
+ font-weight: var(--u-text-subtitle-weight, 600);
40
+ line-height: var(--u-text-subtitle-leading, 1.5);
41
+ letter-spacing: var(--u-text-subtitle-tracking, 0);
42
+ }
43
+
44
+ :host([variant="label"]) .text {
45
+ font-size: var(--u-text-label-size, 13px);
46
+ font-weight: var(--u-text-label-weight, 600);
47
+ line-height: var(--u-text-label-leading, 1.5);
48
+ letter-spacing: var(--u-text-label-tracking, 0);
49
+ }
50
+
51
+ :host([variant="caption"]) .text {
52
+ font-size: var(--u-text-caption-size, 12px);
53
+ font-weight: var(--u-text-caption-weight, 400);
54
+ line-height: var(--u-text-caption-leading, 1.5);
55
+ letter-spacing: var(--u-text-caption-tracking, 0);
56
+ }
57
+
58
+ /*
59
+ * โš  overline ์— text-transform: uppercase ๋ฅผ ๋ถ™์ด์ง€ ์•Š๋Š”๋‹ค.
60
+ *
61
+ * ๋ˆˆ์น ํ…์ŠคํŠธ์˜ ๊ด€์Šต์ด๊ธด ํ•˜๋‚˜ โ‘ด์‹œํŠธ๊ฐ€ ์ •์˜ํ•˜๋Š” ๊ฒƒ์€ ๋„ค ์†์„ฑ๋ฟ์ด๋ผ ๋‹ค์„ฏ ๋ฒˆ์งธ๋ฅผ ์—ฌ๊ธฐ์„œ
62
+ * ์ •ํ•˜๋ฉด ์ด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ยซ๋‘ ๋ฒˆ์งธ ์ •์˜์ฒ˜ยป๊ฐ€ ๋˜๊ณ  โ‘ต์†Œ๋น„์ž๊ฐ€ ์“ด ๊ธ€์ž๋ฅผ ์กฐ์šฉํžˆ ๋ฐ”๊พธ๋ฉฐ
63
+ * โ‘ถCJK ์—๋Š” ์•„๋ฌด ํšจ๊ณผ๊ฐ€ ์—†์–ด **๊ฐ™์€ ๋‹จ์ด ์–ธ์–ด์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ๋ณด์ธ๋‹ค.**
64
+ * ๋Œ€๋ฌธ์ž๊ฐ€ ํ•„์š”ํ•œ ์ž๋ฆฌ๋Š” ๊ทธ ์ž๋ฆฌ๊ฐ€ ์ •ํ•œ๋‹ค.
65
+ */
66
+ :host([variant="overline"]) .text {
67
+ font-size: var(--u-text-overline-size, 11px);
68
+ font-weight: var(--u-text-overline-weight, 700);
69
+ line-height: var(--u-text-overline-leading, 1.45);
70
+ letter-spacing: var(--u-text-overline-tracking, 0.06em);
71
+ }
72
+
73
+ /*
74
+ * tone ์€ **์ค‘๋ฆฝ ๊ฐ•์กฐ ์ถ•**์ด๋‹ค โ€” ์—ญํ• ์ƒ‰(info/success/dangerโ€ฆ)์ด ์•„๋‹ˆ๋‹ค.
75
+ * ์†Œ๋น„์•ฑ ์‹ค์ธก์—์„œ ๋‚˜์˜จ ์ƒ‰ ๋‹ค์„ฏ ์ค‘ ์…‹์ด ์ด ์ถ•์ด์—ˆ๊ณ , ๋‚˜๋จธ์ง€ ๋‘˜์€ ๋งํฌ์™€
76
+ * ์ฝœ์•„์›ƒ ๋ฐ•์Šค๋ผ u-text ์˜ ๋ฌธ์ œ๊ฐ€ ์•„๋‹ˆ์—ˆ๋‹ค.
77
+ */
78
+ :host([tone="weak"]) {
79
+ color: var(--u-txt-color-weak, #757575);
80
+ }
81
+
82
+ :host([tone="strong"]) {
83
+ color: var(--u-txt-color-strong, #000000);
84
+ }
85
+
86
+ :host([tone="inverse"]) {
87
+ color: var(--u-txt-color-inverse, #FFFFFF);
88
+ }
89
+ `;
90
+ //#endregion
91
+ export { styles };
package/dist/index.d.ts CHANGED
@@ -41,6 +41,7 @@ export * from './components/switch/USwitch.js';
41
41
  export * from './components/tab/UTab.js';
42
42
  export * from './components/tab-panel/UTabPanel.js';
43
43
  export * from './components/tag/UTag.js';
44
+ export * from './components/text/UText.js';
44
45
  export * from './components/textarea/UTextarea.js';
45
46
  export * from './components/tooltip/UTooltip.js';
46
47
  export * from './components/tree/UTree.js';
package/dist/index.js CHANGED
@@ -47,6 +47,7 @@ import { USplitPanel } from "./components/split-panel/USplitPanel.js";
47
47
  import { USwitch } from "./components/switch/USwitch.js";
48
48
  import { UTab } from "./components/tab/UTab.js";
49
49
  import { UTabPanel } from "./components/tab-panel/UTabPanel.js";
50
+ import { UText } from "./components/text/UText.js";
50
51
  import { UTextarea } from "./components/textarea/UTextarea.js";
51
52
  import { UTreeItem } from "./components/tree-item/UTreeItem.js";
52
53
  import { UTree } from "./components/tree/UTree.js";
@@ -54,4 +55,4 @@ import { BrowserStorage } from "./utilities/BrowserStorage.js";
54
55
  import { Dialog } from "./utilities/Dialog.js";
55
56
  import { Theme } from "./utilities/Theme.js";
56
57
  import { Toast } from "./utilities/Toast.js";
57
- export { BrowserStorage, Dialog, IconCache, IconRegistry, Locale, OverlayManager, Theme, Toast, UAlert, UAvatar, UBadge, UBreadcrumb, UBreadcrumbItem, UButton, UButtonGroup, UCard, UCarousel, UCheckbox, UChip, UCopyButton, UDialog, UDivider, UDrawer, UElement, UExpander, UField, UFloatingElement, UForm, UFormControlElement, UIcon, UIconButton, UInput, UMenu, UMenuItem, UOption, UOverlayElement, UPanel, UPopover, UProgressBar, UProgressRing, URadio, URating, USelect, USkeleton, USlider, USpinner, USplitPanel, USwitch, UTab, UTabPanel, UTag, UTextarea, UTooltip, UTree, UTreeItem, arrayAttrConverter, booleanAttrConverter, dateAttrConverter, getDefaultBaseUrl, getParentElement, jsonAttrConverter, querySelectorAllWithin, querySelectorWithin, setDefaultBaseUrl, urlAttrConverter };
58
+ export { BrowserStorage, Dialog, IconCache, IconRegistry, Locale, OverlayManager, Theme, Toast, UAlert, UAvatar, UBadge, UBreadcrumb, UBreadcrumbItem, UButton, UButtonGroup, UCard, UCarousel, UCheckbox, UChip, UCopyButton, UDialog, UDivider, UDrawer, UElement, UExpander, UField, UFloatingElement, UForm, UFormControlElement, UIcon, UIconButton, UInput, UMenu, UMenuItem, UOption, UOverlayElement, UPanel, UPopover, UProgressBar, UProgressRing, URadio, URating, USelect, USkeleton, USlider, USpinner, USplitPanel, USwitch, UTab, UTabPanel, UTag, UText, UTextarea, UTooltip, UTree, UTreeItem, arrayAttrConverter, booleanAttrConverter, dateAttrConverter, getDefaultBaseUrl, getParentElement, jsonAttrConverter, querySelectorAllWithin, querySelectorWithin, setDefaultBaseUrl, urlAttrConverter };
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ import { UText as UTextElement } from '../components/text/UText';
3
+
4
+ export declare const UText: React.ForwardRefExoticComponent<
5
+ Omit<Partial<UTextElement>, keyof React.HTMLAttributes<UTextElement>>
6
+ & Omit<React.HTMLAttributes<UTextElement>, never>
7
+ & React.RefAttributes<UTextElement>
8
+ & {
9
+ }
10
+ >;
11
+
12
+ export type UTextProps = React.ComponentProps<typeof UText>;
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import { createComponent } from '@lit/react';
3
+ import { UText as UTextElement } from '../components/text/UText.js';
4
+
5
+ export const UText = createComponent({
6
+ react: React,
7
+ tagName: 'u-text',
8
+ elementClass: UTextElement,
9
+ events: {},
10
+ });
@@ -2,6 +2,7 @@ export { UTreeItem, UTreeItemProps } from './UTreeItem';
2
2
  export { UTree, UTreeProps } from './UTree';
3
3
  export { UTooltip, UTooltipProps } from './UTooltip';
4
4
  export { UTextarea, UTextareaProps } from './UTextarea';
5
+ export { UText, UTextProps } from './UText';
5
6
  export { UTag, UTagProps } from './UTag';
6
7
  export { UTabPanel, UTabPanelProps } from './UTabPanel';
7
8
  export { UTab, UTabProps } from './UTab';
@@ -2,6 +2,7 @@ export { UTreeItem } from './UTreeItem.js';
2
2
  export { UTree } from './UTree.js';
3
3
  export { UTooltip } from './UTooltip.js';
4
4
  export { UTextarea } from './UTextarea.js';
5
+ export { UText } from './UText.js';
5
6
  export { UTag } from './UTag.js';
6
7
  export { UTabPanel } from './UTabPanel.js';
7
8
  export { UTab } from './UTab.js';
@@ -85,6 +85,19 @@ export declare class Theme {
85
85
  *
86
86
  * โš **๋ณ€์ˆ˜๋Š” `documentElement` ์˜ ์ธ๋ผ์ธ ์Šคํƒ€์ผ๋กœ ๋“ค์–ด๊ฐ„๋‹ค** โ€” ์‹œํŠธ๋ณด๋‹ค ์šฐ์„ ํ•˜๋ฏ€๋กœ
87
87
  * ๋กœ๋“œ ์ˆœ์„œ์— ๊ธฐ๋Œ€์ง€ ์•Š๋Š”๋‹ค.
88
+ *
89
+ * ๐Ÿ”ด**`--u-primary-bg-color` ๋Š” ์„ธํŒ…ํ•˜์ง€ ์•Š๋Š”๋‹ค โ€” ์ด ์ž๊ฐ€ ๋ฎ๋Š” ๊ฒƒ์€ 7์ข… ์ค‘ 6์ข…์ด๋‹ค.**
90
+ * ๊ทธ ํ† ํฐ์€ ยซ๊ธ€์ž๋ฅผ ์–น๋Š” ์˜…์€ ๋ฉดยป(`u-tag` ์˜ `--tag-hue-surface`)์ด๋ผ ๋žจํ”„์˜ ์–ด๋А ๋‹จ๊ณผ๋„
91
+ * ์„ฑ์งˆ์ด ๋‹ค๋ฅด๊ณ , ์‹œํŠธ๋Š” ๊ทธ ์ž๋ฆฌ๋ฅผ **5๊ณ„์—ด ร— 2ํ…Œ๋งˆ = 10๊ฐœ ๊ฐ’์œผ๋กœ ์†์ˆ˜ ์ง์ง€์–ด** ๋‘์—ˆ๋‹ค
92
+ * (๋ผ์ดํŠธ/๋‹คํฌ๊ฐ€ ๊ฐ™์€ ๋Œ€๋น„๋น„๋ฅผ ์“ฐ์ง€ ์•Š๋Š”๋‹ค โ€” ์‹ค์ธก 1.14 ๋Œ€ 1.03). ๋„์ถœ์‹์œผ๋กœ ๋ฐ”๊พธ๋Š” ๊ฒƒ์€
93
+ * ํŒ”๋ ˆํŠธ ๊ฐ’ ๊ฒฐ์ •์ด๋ผ ์‚ฌ๋žŒ ํŒ๋‹จ์ด ํ•„์š”ํ•˜๋‹ค.
94
+ *
95
+ * โ‡’ **์‹œ๋“œ๋งŒ ๋„ฃ์œผ๋ฉด ํƒœ๊ทธยท์„ ํƒ๋œ ํ–‰ ๊ฐ™์€ ์˜…์€ ๋ฉด์ด ํŒŒ๋ž‘์œผ๋กœ ๋‚จ๋Š”๋‹ค.** ํ•จ๊ป˜ ์„ธํŒ…ํ•  ๊ฒƒ:
96
+ *
97
+ * ```ts
98
+ * Theme.accent('#7c3aed');
99
+ * document.documentElement.style.setProperty('--u-primary-bg-color', '#f3e8ff');
100
+ * ```
88
101
  */
89
102
  static accent(seed: string | null): void;
90
103
  /** ํ˜„์žฌ ์‹œ๋“œ๋ฅผ ํ˜„์žฌ ํ…Œ๋งˆ์˜ ๋ฐ”ํƒ•์— ๋งž์ถฐ ๋‹ค์‹œ ๊ณ„์‚ฐํ•ด ์ ์šฉํ•œ๋‹ค. */
@@ -186,6 +186,19 @@ var Theme = class {
186
186
  *
187
187
  * โš **๋ณ€์ˆ˜๋Š” `documentElement` ์˜ ์ธ๋ผ์ธ ์Šคํƒ€์ผ๋กœ ๋“ค์–ด๊ฐ„๋‹ค** โ€” ์‹œํŠธ๋ณด๋‹ค ์šฐ์„ ํ•˜๋ฏ€๋กœ
188
188
  * ๋กœ๋“œ ์ˆœ์„œ์— ๊ธฐ๋Œ€์ง€ ์•Š๋Š”๋‹ค.
189
+ *
190
+ * ๐Ÿ”ด**`--u-primary-bg-color` ๋Š” ์„ธํŒ…ํ•˜์ง€ ์•Š๋Š”๋‹ค โ€” ์ด ์ž๊ฐ€ ๋ฎ๋Š” ๊ฒƒ์€ 7์ข… ์ค‘ 6์ข…์ด๋‹ค.**
191
+ * ๊ทธ ํ† ํฐ์€ ยซ๊ธ€์ž๋ฅผ ์–น๋Š” ์˜…์€ ๋ฉดยป(`u-tag` ์˜ `--tag-hue-surface`)์ด๋ผ ๋žจํ”„์˜ ์–ด๋А ๋‹จ๊ณผ๋„
192
+ * ์„ฑ์งˆ์ด ๋‹ค๋ฅด๊ณ , ์‹œํŠธ๋Š” ๊ทธ ์ž๋ฆฌ๋ฅผ **5๊ณ„์—ด ร— 2ํ…Œ๋งˆ = 10๊ฐœ ๊ฐ’์œผ๋กœ ์†์ˆ˜ ์ง์ง€์–ด** ๋‘์—ˆ๋‹ค
193
+ * (๋ผ์ดํŠธ/๋‹คํฌ๊ฐ€ ๊ฐ™์€ ๋Œ€๋น„๋น„๋ฅผ ์“ฐ์ง€ ์•Š๋Š”๋‹ค โ€” ์‹ค์ธก 1.14 ๋Œ€ 1.03). ๋„์ถœ์‹์œผ๋กœ ๋ฐ”๊พธ๋Š” ๊ฒƒ์€
194
+ * ํŒ”๋ ˆํŠธ ๊ฐ’ ๊ฒฐ์ •์ด๋ผ ์‚ฌ๋žŒ ํŒ๋‹จ์ด ํ•„์š”ํ•˜๋‹ค.
195
+ *
196
+ * โ‡’ **์‹œ๋“œ๋งŒ ๋„ฃ์œผ๋ฉด ํƒœ๊ทธยท์„ ํƒ๋œ ํ–‰ ๊ฐ™์€ ์˜…์€ ๋ฉด์ด ํŒŒ๋ž‘์œผ๋กœ ๋‚จ๋Š”๋‹ค.** ํ•จ๊ป˜ ์„ธํŒ…ํ•  ๊ฒƒ:
197
+ *
198
+ * ```ts
199
+ * Theme.accent('#7c3aed');
200
+ * document.documentElement.style.setProperty('--u-primary-bg-color', '#f3e8ff');
201
+ * ```
189
202
  */
190
203
  static accent(seed) {
191
204
  this.accentSeed = seed;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@iyulab/components",
3
3
  "description": "web-components library based on lit-element made by iyulab",
4
- "version": "1.23.0",
4
+ "version": "1.24.0",
5
5
  "keywords": [
6
6
  "iyulab",
7
7
  "components",
@@ -42,14 +42,15 @@
42
42
  "test:browser": "vitest run --project=browser",
43
43
  "lint": "eslint src/",
44
44
  "lint:fix": "eslint src/ --fix",
45
- "build": "eslint && npm run typecheck:plugins && vite build && npm run build:plugins && npm run test:react-types",
45
+ "build": "npm run typecheck && eslint && npm run typecheck:plugins && vite build && npm run build:plugins && npm run test:react-types",
46
46
  "test:react-types": "tsc -p tsconfig.react-smoke.json",
47
47
  "typecheck:plugins": "tsc -p plugins/tsconfig.json",
48
48
  "docs:cssprops": "node scripts/cssprops-doc.mjs --write",
49
49
  "docs:react-events": "node scripts/react-events-doc.mjs --write",
50
50
  "docs:tokens": "node scripts/design-tokens-doc.mjs --write",
51
51
  "build:plugins": "tsc -p plugins/tsconfig.build.json",
52
- "probe:seed-ramp": "node scripts/seed-ramp.mjs"
52
+ "probe:seed-ramp": "node scripts/seed-ramp.mjs",
53
+ "typecheck": "tsc --noEmit"
53
54
  },
54
55
  "dependencies": {
55
56
  "@floating-ui/dom": "^1.8.0",
@@ -59,6 +59,7 @@ import { UButton, UInput } from '@iyulab/components/react';
59
59
 
60
60
  - [`u-button`](./references/components/button.md) โ€” Versatile button with multiple variants; renders as `<a>` when `href` is set
61
61
  - [`u-icon-button`](./references/components/icon-button.md) โ€” Square icon-only button with built-in tooltip
62
+ - [`u-copy-button`](./references/components/copy-button.md) โ€” Copies text to the clipboard with a transient confirmation
62
63
  - [`u-button-group`](./references/components/button-group.md) โ€” Groups buttons with shared variant and disabled state
63
64
 
64
65
  ### Form Controls
@@ -109,6 +110,7 @@ import { UButton, UInput } from '@iyulab/components/react';
109
110
  - [`u-chip`](./references/components/chip.md) โ€” Selectable/removable chip tag
110
111
  - [`u-tag`](./references/components/tag.md) โ€” Non-interactive label tag
111
112
  - [`u-icon`](./references/components/icon.md) โ€” SVG icon from built-in or external icon library
113
+ - [`u-text`](./references/components/text.md) โ€” Semantic typography step; optional heading level
112
114
 
113
115
  ---
114
116
 
@@ -0,0 +1,80 @@
1
+ # u-copy-button
2
+
3
+ ```ts
4
+ import '@iyulab/components/dist/components/copy-button/UCopyButton.js';
5
+ ```
6
+
7
+ **Tag:** `u-copy-button`
8
+
9
+ Copies text to the clipboard and shows a transient confirmation by swapping its icon.
10
+
11
+ Two shapes:
12
+
13
+ - **Icon only** (default) โ€” the default slot becomes the tooltip.
14
+ - **Icon + label** โ€” set `label` to render visible text beside the icon.
15
+
16
+ The clipboard logic is identical in both.
17
+
18
+ ```html
19
+ <!-- Icon only; slot content is the tooltip -->
20
+ <u-copy-button value="npm i @iyulab/components">Copy install command</u-copy-button>
21
+
22
+ <!-- Icon + label -->
23
+ <u-copy-button value="RESULT-1024" label="Copy result"></u-copy-button>
24
+
25
+ <!-- Stays in the copied state until reset explicitly -->
26
+ <u-copy-button value="token" .delay=${0}></u-copy-button>
27
+ ```
28
+
29
+ ## Changing or cancelling what gets copied
30
+
31
+ The `copy` event fires **before** the write, so a handler can rewrite the payload or cancel:
32
+
33
+ ```ts
34
+ button.addEventListener('copy', (e: ClipboardEvent) => {
35
+ e.clipboardData?.setData('text/plain', transform(button.value));
36
+ e.preventDefault(); // cancel the built-in write
37
+ });
38
+ ```
39
+
40
+ ---
41
+
42
+ ## Slots
43
+
44
+ | Name | Description |
45
+ |------|-------------|
46
+ | *(default)* | Tooltip content, icon-only shape. Unused when `label` is set |
47
+
48
+ ## Properties
49
+
50
+ | Property | Type | Default | Reflect | Description |
51
+ |----------|------|---------|---------|-------------|
52
+ | `variant` | `'solid'\|'outline'\|'ghost'\|'link'` | `'ghost'` | โœ“ | Button style |
53
+ | `rounded` | `boolean` | `false` | โœ“ | Circular shape |
54
+ | `disabled` | `boolean` | `false` | โœ“ | Disabled state |
55
+ | `copied` | `boolean` | `false` | โœ“ | Currently showing the copied state |
56
+ | `tooltipPlacement` | `Placement` | `"top"` | | Tooltip placement (`tooltip-placement`) |
57
+ | `tooltipOffset` | `OffsetOptions` | `4` | | Tooltip distance (`tooltip-offset`) |
58
+ | `delay` | `number` | `1_000` | | Milliseconds before leaving the copied state; `0` or less keeps it |
59
+ | `value` | `string` | โ€” | | Text to copy |
60
+ | `label` | `string` | โ€” | | Inline label; switches to the icon + label shape |
61
+
62
+ ## Events
63
+
64
+ | Event | Detail | Description |
65
+ |-------|--------|-------------|
66
+ | `copy` | native `ClipboardEvent` | Fires before the write. `preventDefault()` cancels it; `clipboardData.setData` replaces the payload |
67
+
68
+ ## CSS Parts
69
+
70
+ | Part | Description |
71
+ |------|-------------|
72
+ | `button` | Inner button element |
73
+ | `icon` | Icon element |
74
+ | `tooltip` | Tooltip element (icon-only shape) |
75
+
76
+ ## Sizing
77
+
78
+ This component keeps a **fixed** font size (18px) rather than inheriting the surrounding
79
+ typography โ€” it reads as an affordance next to text of any size. See
80
+ [design-tokens.md](../../../../docs/design-tokens.md) for the four components that do this.
@@ -30,8 +30,19 @@ Renders an SVG icon by name from a registered icon library. Inline `src` also ac
30
30
  <u-icon src='<svg ...>...</svg>'></u-icon>
31
31
  ```
32
32
 
33
+ ```html
34
+ <!-- Fallback: drawn when the name does not resolve -->
35
+ <u-icon name="might-not-exist" fallback='<svg viewBox="0 0 16 16">...</svg>'></u-icon>
36
+ ```
37
+
33
38
  For registering custom libraries, see [icons.md](../utilities/icons.md).
34
39
 
40
+ > **When you need `fallback`.** An icon that fails to resolve renders nothing. That is usually
41
+ > harmless โ€” but not where the icon is the only hit target. A collapsed sidebar hides labels, so
42
+ > a nav item with no visible icon becomes an **empty row the user cannot click**: the screen
43
+ > becomes unreachable. `fallback` covers all three failure modes (no `name`, 404, unparseable SVG).
44
+ > Keep the fallback **inline**; a fallback that fetches reproduces the very failure it covers.
45
+
35
46
  ---
36
47
 
37
48
  ## Properties
@@ -41,6 +52,7 @@ For registering custom libraries, see [icons.md](../utilities/icons.md).
41
52
  | `lib` | `'internal'\|'tabler'\|'heroicons'\|'lucide'\|'bootstrap'\|string` | โ€” | Icon library identifier |
42
53
  | `name` | `string` | โ€” | Icon name (library-specific; append `:filled` / `:solid` for filled variants) |
43
54
  | `src` | `string` | โ€” | Raw SVG string (overrides `lib`/`name`) |
55
+ | `fallback` | `string` | โ€” | Raw SVG drawn when `name`/`src` cannot be resolved (missing, 404, or unparseable) |
44
56
 
45
57
  ## CSS Parts
46
58
 
@@ -0,0 +1,79 @@
1
+ # u-text
2
+
3
+ ```ts
4
+ import '@iyulab/components/dist/components/text/UText.js';
5
+ ```
6
+
7
+ **Tag:** `u-text`
8
+
9
+ Semantic typography. Applies one of the seven design-token type steps
10
+ (`display` โ†’ `overline`) so markup can use the scale without any consumer CSS.
11
+ The component reads the token sheet โ€” it never defines its own type values.
12
+
13
+ ```html
14
+ <u-text level="1" variant="display">Document title</u-text>
15
+ <u-text variant="subtitle" tone="weak">One-line description</u-text>
16
+
17
+ <u-text>Body copy is the default step.</u-text>
18
+ <u-text variant="caption" tone="weak">Helper text</u-text>
19
+
20
+ <u-text variant="overline">Section</u-text>
21
+ ```
22
+
23
+ ## Visual step and heading level are independent
24
+
25
+ `variant` chooses how the text *looks*; `level` chooses what it *is*. When
26
+ `level` is set the component renders a real `<h1>`โ€“`<h6>` in its shadow root, so
27
+ assistive technology reads it as a heading whose accessible name is the slotted
28
+ text. Without `level` it renders a `<p>`.
29
+
30
+ ```html
31
+ <!-- Second-level heading that is visually the largest thing on the page -->
32
+ <u-text level="2" variant="display">Overview</u-text>
33
+ ```
34
+
35
+ This keeps the document outline honest while leaving the visual hierarchy free.
36
+
37
+ > **Do not nest a heading inside the slot** โ€” `<u-text><h2>โ€ฆ</h2></u-text>` makes
38
+ > the UA rule `h2 { font-size: 1.5em }` multiply the step's font size. Use
39
+ > `level` instead. Wrapping the other way (`<h2><u-text>โ€ฆ</u-text></h2>`) is safe
40
+ > because the steps are absolute sizes, but the outer heading keeps its UA
41
+ > margin, so `level` is still the simpler choice.
42
+
43
+ ## Colour
44
+
45
+ `tone` is a **neutral emphasis axis**, not a role-colour axis. Semantic status
46
+ colour belongs to the component that owns the status (`u-alert`, `u-tag`,
47
+ `u-badge`), and link colour belongs to the link.
48
+
49
+ ---
50
+
51
+ ## Slots
52
+
53
+ | Name | Description |
54
+ |------|-------------|
55
+ | *(default)* | Text content |
56
+
57
+ ## Properties
58
+
59
+ | Property | Type | Default | Reflect | Description |
60
+ |----------|------|---------|---------|-------------|
61
+ | `variant` | `'display'\|'title'\|'subtitle'\|'body'\|'label'\|'caption'\|'overline'` | `'body'` | โœ“ | Semantic type step |
62
+ | `tone` | `'default'\|'weak'\|'strong'\|'inverse'` | `'default'` | โœ“ | Neutral emphasis axis |
63
+ | `level` | `1\|2\|3\|4\|5\|6` | โ€” | โœ“ | Heading level; renders `<h1>`โ€“`<h6>` |
64
+
65
+ ## CSS Parts
66
+
67
+ | Part | Description |
68
+ |------|-------------|
69
+ | `base` | The rendered `<p>` or `<h1>`โ€“`<h6>` element |
70
+
71
+ ## Design tokens read
72
+
73
+ | Step | Tokens |
74
+ |------|--------|
75
+ | `display` ยท `title` ยท `subtitle` ยท `body` ยท `label` ยท `caption` ยท `overline` | `--u-text-{step}-size`, `--u-text-{step}-weight`, `--u-text-{step}-leading`, `--u-text-{step}-tracking` |
76
+ | `tone` | `--u-txt-color`, `--u-txt-color-weak`, `--u-txt-color-strong`, `--u-txt-color-inverse` |
77
+
78
+ Spacing between blocks is **not** this component's concern โ€” it has no margin.
79
+ The surrounding layout decides rhythm (`u-group-box`, `u-card`, a flex column).
@@ -78,6 +78,32 @@ accent surface โ‰ฅ 4.5:1, accent text on the page background โ‰ฅ 4.5:1, `-strong
78
78
  from `-color`, and `-weak` usable as a non-text graphic (โ‰ฅ 3:1). It is **recalculated when the
79
79
  theme changes**, because those targets are relative to the page background.
80
80
 
81
+ #### How many tokens does the `primary` role have? **Seven.**
82
+
83
+ `Theme.accent()` sets **six** of them:
84
+
85
+ | Token | `Theme.accent()` | What reads it |
86
+ |---|---|---|
87
+ | `--u-primary-color` | โœ… | accent surface โ€” 21 source files |
88
+ | `--u-primary-color-strong` | โœ… | text/icons on the page background; hover ยท active ยท link ยท focus ring โ€” 14 files |
89
+ | `--u-primary-color-weak` | โœ… | non-text graphics |
90
+ | `--u-primary-color-weaker` | โœ… | decorative |
91
+ | `--u-primary-color-weakest` | โœ… | decorative |
92
+ | `--u-primary-txt-color` | โœ… | text on the accent surface |
93
+ | **`--u-primary-bg-color`** | ๐Ÿ”ด**no** | tinted **surface behind text** โ€” `u-tag`'s `--tag-hue-surface` |
94
+
95
+ ๐Ÿ”ด **`Theme.accent()` does not touch `--u-primary-bg-color`.** It stays on the sheet default
96
+ (a blue tint), so a seeded brand leaves tinted surfaces blue. Set it yourself alongside the seed:
97
+
98
+ ```ts
99
+ Theme.accent('#7c3aed');
100
+ document.documentElement.style.setProperty('--u-primary-bg-color', '#f3e8ff');
101
+ ```
102
+
103
+ Pick a tint that keeps your body text readable on it โ€” the built-in sheet values sit at roughly
104
+ 1.14:1 (light) and 1.03:1 (dark) against the page background. Deriving this step automatically is
105
+ tracked as open work, because the sheet pairs it by hand across five colour roles and two themes.
106
+
81
107
  **Manual override** โ€” you must set the steps you use, not just one:
82
108
 
83
109
  ```css
@@ -86,11 +112,36 @@ theme changes**, because those targets are relative to the page background.
86
112
  --u-primary-color: #7c3aed; /* accent surface */
87
113
  --u-primary-color-strong: #5b21b6; /* text/icons on the page background */
88
114
  --u-primary-txt-color: #ffffff; /* text on the accent surface */
115
+ --u-primary-bg-color: #f3e8ff; /* tinted surface behind text */
89
116
  }
90
117
  ```
91
118
 
92
119
  โš  Setting `--u-primary-color` alone is **not enough**: hover/focus/link colors resolve from
93
120
  `--u-primary-color-strong`, so they stay on the default ramp and your brand looks half-applied.
121
+ The measured symptom is a *selected table row* or *tag* that stays blue while buttons turn brand โ€”
122
+ that one is `--u-primary-bg-color`.
123
+
124
+ ### Typography
125
+
126
+ The sheet defines seven semantic steps โ€” `display`, `title`, `subtitle`, `body`, `label`,
127
+ `caption`, `overline` โ€” each with `-size`, `-weight`, `-leading`, `-tracking`. Use them from
128
+ markup with [`u-text`](./components/text.md) instead of writing your own CSS:
129
+
130
+ ```html
131
+ <u-text level="1" variant="display">Document title</u-text>
132
+ <u-text variant="subtitle" tone="weak">One-line description</u-text>
133
+ <u-text>Body copy</u-text>
134
+ <u-text variant="caption" tone="weak">Helper text</u-text>
135
+ ```
136
+
137
+ `variant` is the visual step and `level` is the document level โ€” they are independent, and
138
+ `level` renders a real `<h1>`โ€“`<h6>` so the heading is read as one.
139
+
140
+ To rebrand typography, override the tokens rather than the screens:
141
+
142
+ ```css
143
+ :root { --u-text-title-size: 22px; --u-text-title-weight: 800; }
144
+ ```
94
145
 
95
146
  ---
96
147