@hjmds/design-contracts 1.10.0 → 1.12.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/dist/action-session.d.ts +47 -0
- package/dist/action-session.d.ts.map +1 -0
- package/dist/action-session.js +60 -0
- package/dist/action-session.js.map +1 -0
- package/dist/activity-heatmap.d.ts +22 -0
- package/dist/activity-heatmap.d.ts.map +1 -0
- package/dist/activity-heatmap.js +29 -0
- package/dist/activity-heatmap.js.map +1 -0
- package/dist/auth-screen.d.ts +4 -0
- package/dist/auth-screen.d.ts.map +1 -1
- package/dist/auth-screen.js +2 -0
- package/dist/auth-screen.js.map +1 -1
- package/dist/avatar-fallback.d.ts +25 -0
- package/dist/avatar-fallback.d.ts.map +1 -0
- package/dist/avatar-fallback.js +17 -0
- package/dist/avatar-fallback.js.map +1 -0
- package/dist/behaviors.d.ts +2 -2
- package/dist/bottom-navigation-defaults.d.ts +1 -1
- package/dist/bottom-navigation-defaults.d.ts.map +1 -1
- package/dist/bottom-navigation-defaults.js.map +1 -1
- package/dist/bottom-navigation.d.ts.map +1 -1
- package/dist/bottom-navigation.js +5 -1
- package/dist/bottom-navigation.js.map +1 -1
- package/dist/catalog.d.ts +30 -1
- package/dist/catalog.d.ts.map +1 -1
- package/dist/code-block.d.ts +23 -0
- package/dist/code-block.d.ts.map +1 -0
- package/dist/code-block.js +13 -0
- package/dist/code-block.js.map +1 -0
- package/dist/component-definitions.d.ts +2 -3
- package/dist/component-definitions.d.ts.map +1 -1
- package/dist/component-definitions.js +1 -2
- package/dist/component-definitions.js.map +1 -1
- package/dist/component-recipes.d.ts +25 -1
- package/dist/component-recipes.d.ts.map +1 -1
- package/dist/component-recipes.js +12 -1
- package/dist/component-recipes.js.map +1 -1
- package/dist/component-references.d.ts +0 -6
- package/dist/component-references.d.ts.map +1 -1
- package/dist/component-references.js +0 -5
- package/dist/component-references.js.map +1 -1
- package/dist/content-transition.d.ts +17 -0
- package/dist/content-transition.d.ts.map +1 -0
- package/dist/content-transition.js +15 -0
- package/dist/content-transition.js.map +1 -0
- package/dist/duration-field.d.ts +22 -0
- package/dist/duration-field.d.ts.map +1 -0
- package/dist/duration-field.js +20 -0
- package/dist/duration-field.js.map +1 -0
- package/dist/effect-surface.d.ts +29 -0
- package/dist/effect-surface.d.ts.map +1 -0
- package/dist/effect-surface.js +26 -0
- package/dist/effect-surface.js.map +1 -0
- package/dist/gooey-navigation.d.ts +13 -0
- package/dist/gooey-navigation.d.ts.map +1 -0
- package/dist/gooey-navigation.js +11 -0
- package/dist/gooey-navigation.js.map +1 -0
- package/dist/gravity-letters.d.ts +12 -0
- package/dist/gravity-letters.d.ts.map +1 -0
- package/dist/gravity-letters.js +11 -0
- package/dist/gravity-letters.js.map +1 -0
- package/dist/grid-reveal.d.ts +8 -0
- package/dist/grid-reveal.d.ts.map +1 -0
- package/dist/grid-reveal.js +5 -0
- package/dist/grid-reveal.js.map +1 -0
- package/dist/internal/object-validation.d.ts +3 -0
- package/dist/internal/object-validation.d.ts.map +1 -0
- package/dist/internal/object-validation.js +12 -0
- package/dist/internal/object-validation.js.map +1 -0
- package/dist/internal/thinking-orb/braid.d.ts.map +1 -1
- package/dist/internal/thinking-orb/braid.js +2 -9
- package/dist/internal/thinking-orb/braid.js.map +1 -1
- package/dist/internal/thinking-orb/core.d.ts +1 -0
- package/dist/internal/thinking-orb/core.d.ts.map +1 -1
- package/dist/internal/thinking-orb/core.js +12 -0
- package/dist/internal/thinking-orb/core.js.map +1 -1
- package/dist/internal/thinking-orb/presentation.d.ts +4 -0
- package/dist/internal/thinking-orb/presentation.d.ts.map +1 -0
- package/dist/internal/thinking-orb/presentation.js +28 -0
- package/dist/internal/thinking-orb/presentation.js.map +1 -0
- package/dist/internal/thinking-orb/ribbon.d.ts.map +1 -1
- package/dist/internal/thinking-orb/ribbon.js +2 -9
- package/dist/internal/thinking-orb/ribbon.js.map +1 -1
- package/dist/layout.d.ts +0 -5
- package/dist/layout.d.ts.map +1 -1
- package/dist/layout.js +0 -7
- package/dist/layout.js.map +1 -1
- package/dist/otp-field.d.ts +2 -0
- package/dist/otp-field.d.ts.map +1 -1
- package/dist/otp-field.js.map +1 -1
- package/dist/popover.d.ts.map +1 -1
- package/dist/popover.js +3 -12
- package/dist/popover.js.map +1 -1
- package/dist/progress-recipe.d.ts +1 -0
- package/dist/progress-recipe.d.ts.map +1 -1
- package/dist/progress-recipe.js +2 -1
- package/dist/progress-recipe.js.map +1 -1
- package/dist/reactions.d.ts +10 -0
- package/dist/reactions.d.ts.map +1 -0
- package/dist/reactions.js +20 -0
- package/dist/reactions.js.map +1 -0
- package/dist/scroll-progress.d.ts +8 -0
- package/dist/scroll-progress.d.ts.map +1 -0
- package/dist/scroll-progress.js +10 -0
- package/dist/scroll-progress.js.map +1 -0
- package/dist/steps.d.ts +1 -1
- package/dist/steps.d.ts.map +1 -1
- package/dist/steps.js +2 -1
- package/dist/steps.js.map +1 -1
- package/dist/task-list.d.ts +7 -0
- package/dist/task-list.d.ts.map +1 -0
- package/dist/task-list.js +4 -0
- package/dist/task-list.js.map +1 -0
- package/dist/theme-studio.d.ts +14 -0
- package/dist/theme-studio.d.ts.map +1 -0
- package/dist/theme-studio.js +16 -0
- package/dist/theme-studio.js.map +1 -0
- package/dist/thinking-orb.d.ts +4 -2
- package/dist/thinking-orb.d.ts.map +1 -1
- package/dist/thinking-orb.js +8 -3
- package/dist/thinking-orb.js.map +1 -1
- package/dist/toast-liquid.d.ts +4 -4
- package/dist/toast-liquid.d.ts.map +1 -1
- package/dist/toast-liquid.js +11 -10
- package/dist/toast-liquid.js.map +1 -1
- package/dist/toast.d.ts +4 -4
- package/dist/toast.d.ts.map +1 -1
- package/dist/toast.js +4 -3
- package/dist/toast.js.map +1 -1
- package/dist/tooltip.d.ts.map +1 -1
- package/dist/tooltip.js +3 -12
- package/dist/tooltip.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/dist/voice-note.d.ts +20 -0
- package/dist/voice-note.d.ts.map +1 -0
- package/dist/voice-note.js +16 -0
- package/dist/voice-note.js.map +1 -0
- package/docs/action-session.md +73 -0
- package/docs/activity-heatmap.md +32 -0
- package/docs/anchor.md +1 -1
- package/docs/auth-screen.md +44 -4
- package/docs/authoring-brief.md +5 -0
- package/docs/avatar-fallback.md +74 -0
- package/docs/bottom-navigation.md +16 -1
- package/docs/breadcrumb.md +1 -1
- package/docs/calendar.md +1 -1
- package/docs/cascader.md +1 -1
- package/docs/code-block.md +32 -0
- package/docs/command-palette.md +1 -1
- package/docs/compound-controls.md +83 -0
- package/docs/confirm-popover.md +1 -1
- package/docs/consumer-policy.md +30 -23
- package/docs/cross-platform-core-normalization.md +23 -21
- package/docs/data-table.md +8 -5
- package/docs/dialog.md +2 -0
- package/docs/effect-surface.md +50 -0
- package/docs/floating-action-button.md +1 -1
- package/docs/folder-preview.md +26 -0
- package/docs/generated/component-maturity.md +1 -1
- package/docs/generated/renderer-evidence.json +3 -3
- package/docs/generated/renderer-evidence.md +1 -1
- package/docs/generated/showcase-manifest.json +1 -1
- package/docs/gooey-navigation.md +36 -0
- package/docs/gravity-letters.md +26 -0
- package/docs/grid-reveal.md +11 -0
- package/docs/icon.md +26 -0
- package/docs/image.md +2 -2
- package/docs/layout.md +1 -2
- package/docs/load-more.md +3 -1
- package/docs/migration-0.5.md +4 -1
- package/docs/migration-native-legacy-removal.md +60 -0
- package/docs/navigation-bar.md +28 -0
- package/docs/optional-adapters.md +24 -1
- package/docs/otp-field.md +23 -1
- package/docs/pagination.md +1 -1
- package/docs/popover.md +2 -2
- package/docs/product-adoption-1.4.md +7 -0
- package/docs/product-audit-2026-09-15.md +1 -1
- package/docs/progress.md +8 -0
- package/docs/provider-button.md +10 -3
- package/docs/rating.md +1 -1
- package/docs/react-native-completion.md +4 -4
- package/docs/screen-chrome.md +2 -2
- package/docs/scroll-progress.md +29 -0
- package/docs/sheet.md +2 -0
- package/docs/sidebar.md +6 -0
- package/docs/splitter.md +1 -1
- package/docs/step-player.md +16 -0
- package/docs/steps.md +9 -3
- package/docs/task-list.md +32 -0
- package/docs/theme-studio.md +13 -0
- package/docs/thinking-orb.md +9 -2
- package/docs/time-picker.md +1 -1
- package/docs/toast.md +8 -7
- package/docs/tour.md +1 -1
- package/docs/tree-select.md +2 -2
- package/docs/voice-note.md +19 -0
- package/package.json +91 -1
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Gooey navigation
|
|
2
|
+
|
|
3
|
+
Reviewed: 2026-10-01
|
|
4
|
+
|
|
5
|
+
Use the existing `Tabs` from `@hjmds/react/navigation` or
|
|
6
|
+
`@hjmds/react-native/navigation` with `appearance="gooey"`. The default remains
|
|
7
|
+
`standard`. A new navigation controller would duplicate existing selection,
|
|
8
|
+
keyboard, disabled-item and panel contracts, so only the selected indicator is
|
|
9
|
+
extended. Vertical tabs deliberately retain the standard line: stretching a
|
|
10
|
+
horizontal bridge across a vertical list would obscure unrelated items.
|
|
11
|
+
|
|
12
|
+
`@hjmds/design-contracts/gooey-navigation` owns the measured source/destination
|
|
13
|
+
bridge. It expands to the union of their edges at 45% progress, then contracts to
|
|
14
|
+
the destination over 320ms. This independently authored elastic presentation
|
|
15
|
+
uses no copied effects, shader or physics engine. Six-point indicator height is
|
|
16
|
+
decorative geometry; colors and corner radius reuse tokens. Text and hit targets
|
|
17
|
+
never transform. On Web, selected-tab measurements and ResizeObserver track
|
|
18
|
+
font/viewport changes; Native uses tab onLayout measurements. Measured physical
|
|
19
|
+
coordinates also support RTL and horizontal scrolling.
|
|
20
|
+
|
|
21
|
+
Reduced motion, backgrounding and cleanup settle the indicator without changing
|
|
22
|
+
selection. Native width animation uses Core Animated's JS driver because width
|
|
23
|
+
cannot use the native transform driver without distorting corner radii. No new
|
|
24
|
+
optional animation dependency is introduced. Rapid re-selection targets the last
|
|
25
|
+
selected tab; this is deterministic selection feedback, not a physics simulation.
|
|
26
|
+
|
|
27
|
+
Both Storybooks expose `컴포넌트 / 탐색 / Gooey Navigation` with Default,
|
|
28
|
+
Dark and LargeText plus a direction toggle. Disabled tabs, existing activation
|
|
29
|
+
mode and panel associations remain canonical. The Native renderer is tested with
|
|
30
|
+
mock layout events; actual device appearance remains to be verified.
|
|
31
|
+
|
|
32
|
+
Native horizontal scrollable Tabs centers the selected measured tab within the scroll
|
|
33
|
+
content bounds when selection, direction or viewport width changes. This corrects a
|
|
34
|
+
LargeText RTL selected-label clipping issue found in the [device flow audit](../../../docs/evidence/component-flows-2026-10-01/README.md).
|
|
35
|
+
The standard appearance shares this behavior; fitted and non-scrollable lists do not
|
|
36
|
+
programmatically scroll. Selection semantics and the host's panel ownership are unchanged.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Gravity Letters
|
|
2
|
+
|
|
3
|
+
Reviewed: 2026-10-01
|
|
4
|
+
|
|
5
|
+
Optional `@hjmds/react/gravity-letters` and `@hjmds/react-native/gravity-letters`
|
|
6
|
+
provide an independently authored promotional drop/rebound accent. This is not a
|
|
7
|
+
replacement for Text or ContentTransition: the whole effect is decorative and
|
|
8
|
+
hidden from accessibility APIs. Keep the meaningful static heading outside it.
|
|
9
|
+
The Web presentation inherits typography; Native uses canonical heading Text.
|
|
10
|
+
|
|
11
|
+
Pass `glyphs` as host-segmented graphemes/words (at most 32 nonempty single-line
|
|
12
|
+
strings). Never split emoji or complex scripts with UTF-16 `split("")`. Spaces
|
|
13
|
+
are preserved. The bound prevents a headline effect becoming paragraph-scale
|
|
14
|
+
animation work. `active` defaults to false; set true and change `replayKey` for an
|
|
15
|
+
explicit replay. No timer, physics dependency or pointer gesture is installed.
|
|
16
|
+
|
|
17
|
+
The contract owns the 36-point drop, small rebound, alternating tilt and 24ms
|
|
18
|
+
stagger. These are decorative geometry, not layout spacing tokens. The reserved
|
|
19
|
+
upper inset keeps the drop inside the component bounds. Web WAAPI and Native Core
|
|
20
|
+
Animated cancel on inactivity, reduced motion, backgrounding, replacement or
|
|
21
|
+
unmount; text rests at its final position. Foregrounding alone does not replay.
|
|
22
|
+
|
|
23
|
+
Both Storybooks: `컴포넌트 / Display / Gravity Letters`, with Default, Dark
|
|
24
|
+
and LargeText. Web glyph typography can be inherited from a surrounding heading
|
|
25
|
+
Text. Renderer behavior tests cover explicit replay and motion bypass; Native
|
|
26
|
+
mock tests do not prove actual device rendering.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# GridReveal
|
|
2
|
+
|
|
3
|
+
검토일: 2026-10-01.
|
|
4
|
+
|
|
5
|
+
`@hjmds/react/grid-reveal`, `@hjmds/react-native/grid-reveal`는 기존 Image 주위에 합성하는 장식 마스크다. `ready`를 Image의 `onLoadStatusChange`가 loaded일 때만 true로 두고, 이미지 소스 변경/재시도 전에는 false로 초기화한다. 오류일 때는 false로 돌린다. Image의 크기 예약·접근성 이름·로딩·실패·재시도 동작은 그대로 유지한다.
|
|
6
|
+
|
|
7
|
+
`children`이 실제 콘텐츠를 소유한다. `active=false`는 숨겨진 화면의 효과를 중단한다. 격자 4×4와 최대 180ms 지연, 기존 normal 지속 시간을 공유한다. 마스크만 투명해지며 이미지 픽셀·터치 대상·접근성 트리를 복제하지 않는다. 모션 줄이기에서는 마스크를 생략하고 이미지를 바로 보여준다. 웹 문서 숨김 또는 Native AppState 비활성에서도 마스크를 지운다.
|
|
8
|
+
|
|
9
|
+
Web은 WAAPI, Native는 Core Animated를 사용한다. Native 화면이 mounted인 채 가려지면 제품이 active=false를 전달해야 한다. 부모를 이미지 크기에 맞게 배치하며, 둥근 이미지 모서리가 필요하면 동일한 클리핑 프레임으로 둘을 감싼다.
|
|
10
|
+
|
|
11
|
+
양쪽 Storybook 컴포넌트/시각 효과/Grid Reveal에서 Default/Dark/LargeText, 다시 보기와 이미지 실패/재시도를 제공한다. 예제 풍경은 코드로 만든 자체 이미지다. [Native 후속 검증](../../../docs/evidence/component-flows-2026-10-01/README.md)에서 기존 iPhone 17 / iOS 27 시뮬레이터의 큰 글씨 오류·재시도 화면을 실제 조작하고 확인했다. Image 계약에 따라 오류 전후 같은 이미지 설명을 유지하며, 시각적 오류 문구는 중복 접근성 이름으로 읽지 않는다. 물리 기기의 GPU 비용과 프레임별 효과 타이밍 검증은 별도다.
|
package/docs/icon.md
CHANGED
|
@@ -20,3 +20,29 @@ name을 제품 adapter가 Web SVG 또는 React Native glyph로 번역해, 아이
|
|
|
20
20
|
|
|
21
21
|
WAI의 기준처럼 주변 텍스트와 중복되는 그림은 장식으로 숨기고, 기능을 단독으로 전달하는
|
|
22
22
|
그림은 모양 이름이 아니라 동작/목적을 접근성 이름으로 제공합니다.
|
|
23
|
+
|
|
24
|
+
## Lucide adapter — 2026-10-01
|
|
25
|
+
|
|
26
|
+
`createLucideGlyph` from either renderer `/icon-lucide` entry accepts named
|
|
27
|
+
Lucide imports mapped to semantic names. This keeps only the selected glyphs
|
|
28
|
+
reachable; it never loads a dynamic full-library dictionary.
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
import { Search, ArrowLeft } from 'lucide-react';
|
|
32
|
+
import { createLucideGlyph } from '@hjmds/react/icon-lucide';
|
|
33
|
+
const renderGlyph = createLucideGlyph({ search: Search, back: ArrowLeft });
|
|
34
|
+
// Web: <Icon name="search" renderGlyph={renderGlyph} />
|
|
35
|
+
// Native: use lucide-react-native and <Icon descriptor={{name:'search'}} renderGlyph={renderGlyph}/>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Web now supports an optional `renderGlyph` inside its existing SVG frame. Omit it
|
|
39
|
+
or return null to preserve the built-in glyph. Its callback receives a 24-unit
|
|
40
|
+
viewBox size and currentColor; the outer frame resolves the actual token size.
|
|
41
|
+
Native receives resolved numeric size/color/stroke and retains its existing
|
|
42
|
+
renderGlyph contract. Both adapters hide artwork and leave naming, directionality
|
|
43
|
+
and mirroring on Icon. Missing map entries throw to reveal product mapping errors.
|
|
44
|
+
|
|
45
|
+
Lucide 1.49.0 is the verified development/showcase version and optional peer.
|
|
46
|
+
The Native factory uses a scalar-only component interface instead of exporting
|
|
47
|
+
one host version's RN StyleProp types, keeping consumers on supported newer RN
|
|
48
|
+
versions structurally compatible. This does not replace provider/brand logos.
|
package/docs/image.md
CHANGED
|
@@ -75,8 +75,8 @@ intrinsic ratio 예약, 장식/정보 이미지의 alt 의미, load/error 상태
|
|
|
75
75
|
`nativeResizeModes`로 fit을 번역하며, 장식 기본값·정보 이미지의 fallback 이름 유지·built-in
|
|
76
76
|
fallback·`src` 변경 후 재시도를 component test로 검증한다. `sourceAdapter`와 `renderImage`
|
|
77
77
|
경계로 bare RN의 `ImageSourcePropType` 및 `expo-image` 같은 optimized host를 연결할 수 있다.
|
|
78
|
-
이전 RN `source`
|
|
79
|
-
|
|
78
|
+
이전 RN `source` 호환 경로는 다음 major 소스에서 제거했다. 이관은
|
|
79
|
+
[Native 호환 별칭 제거](./migration-native-legacy-removal.md)를 따른다.
|
|
80
80
|
|
|
81
81
|
이전 후보였던 야잘알 팀 엠블럼은 여전히 Avatar 성격이므로 Image의 제품 증거로 세지 않고,
|
|
82
82
|
BurnTok의 data URI 아이콘도 network failure 증거로 세지 않는다. 실제 network asset의
|
package/docs/layout.md
CHANGED
|
@@ -22,8 +22,7 @@ stable)이다. `Layout`이 그 콘텐츠나 상태를 다시 계약하면 두
|
|
|
22
22
|
Web 전용 `validateLayoutWebDescriptor`가 이 규칙을 강제한다 — `hasHeader`나
|
|
23
23
|
`sidebar`가 있는데 `skipLinkLabel`이 없으면 던진다. 공통
|
|
24
24
|
`validateLayoutRegions`는 region/sidebar 구조만 검사하므로, bypass-link 개념이
|
|
25
|
-
없는 Native에 Web 요구를 강제하지 않는다. 기존 `validateLayoutDescriptor
|
|
26
|
-
Web validator의 호환 alias다.
|
|
25
|
+
없는 Native에 Web 요구를 강제하지 않는다. 기존 `validateLayoutDescriptor` 호환 alias는 2.0에서 제거했다.
|
|
27
26
|
- **플랫폼 번역**: 성립하지만 비대칭적으로 성립한다. Web은 실제 랜드마크
|
|
28
27
|
엘리먼트(`<header>`/`<nav>`/`<main>`/`<footer>`)가 있다. Native는 랜드마크
|
|
29
28
|
개념 자체가 없다 — `accessibilityRole`은 heading/control용이지 페이지 영역용이
|
package/docs/load-more.md
CHANGED
|
@@ -11,7 +11,9 @@ ready(requestKey) ─ request ─→ loading(requestKey)
|
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
- `requestKey`는 cursor나 offset을 제품 adapter가 stable string으로 만든 값입니다.
|
|
14
|
-
- `labels`는 load more/loading/retry/complete 네 상태의 현지화된
|
|
14
|
+
- `labels`는 load more/loading/retry/complete 네 상태의 현지화된 이름입니다. loading은
|
|
15
|
+
2026-10-02 사용자 요청에 따라 화면에 스피너만 보이고 접근성 이름으로 남습니다. 이전의
|
|
16
|
+
스피너 옆 문구는 같은 상태를 중복 표시하므로 제거했습니다. renderer가
|
|
15
17
|
자체 문구나 영어 fallback을 만들지 않습니다.
|
|
16
18
|
- `createLoadMoreController`는 한 controller에서 요청 하나만 허용합니다. 같은 sentinel의 반복
|
|
17
19
|
노출이나 RN `onEndReached` 중복 호출이 query를 두 번 실행하지 못합니다.
|
package/docs/migration-0.5.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# v0.5 migration
|
|
2
2
|
|
|
3
|
+
이 문서는 0.5 당시의 이관 기록이다. 여기서 유지한다고 설명한 coverage 별칭은
|
|
4
|
+
[2.0 이관](migration-native-legacy-removal.md)에서 제거했으며 현재 API 지원을 뜻하지 않는다.
|
|
5
|
+
|
|
3
6
|
v0.4 → v0.5는 기존 foundation/recipe 런타임 값을 유지하는 additive release입니다. 다만
|
|
4
7
|
catalog status를 그대로 열거하거나 Showcase route 존재를 renderer 증거로 사용한 소비자는
|
|
5
8
|
아래 두 가지를 확인해야 합니다.
|
|
@@ -65,7 +68,7 @@ value.palette;
|
|
|
65
68
|
|
|
66
69
|
- 91개 canonical route를 Web reference, contract-only, Web unsupported로 분리합니다.
|
|
67
70
|
- planned route는 구현된 것처럼 보이는 JSX를 렌더링하지 않습니다.
|
|
68
|
-
-
|
|
71
|
+
- 시작하기/Explorer 수치는 실제 evidence registry에서 계산합니다.
|
|
69
72
|
- Storybook manager와 preview가 foundation token을 사용합니다.
|
|
70
73
|
- token-boundary 검사와 static classification 검사가 Showcase check에 포함됩니다.
|
|
71
74
|
- Ant Design reference는 6.6.1로 고정됩니다. v0.7부터 외부 registry drift 검사는 자동 CI가
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# 1.11 호환 API 제거와 소비 이관
|
|
2
|
+
|
|
3
|
+
검토일: 2026-10-02 · 1.11 minor 소스 변경 · npm 게시와 소비 설치는 별도 확인
|
|
4
|
+
|
|
5
|
+
사용자가 전체 소비 앱을 함께 버전업하므로 구형 호환 API도 제거하라고 요청했다.
|
|
6
|
+
별칭과 deprecated 스타일 통로를 유지하는 대신 기존 canonical API로 이관한다.
|
|
7
|
+
2026-10-02 사용자 결정에 따라 호환 API 제거를 1.11.0 minor Changeset에 포함한다.
|
|
8
|
+
기존 1.x 소비자는 정확한 버전을 고정한 상태에서 이 이관표를 적용한 뒤 올려야 한다.
|
|
9
|
+
|
|
10
|
+
| 제거 | 대체 |
|
|
11
|
+
| --- | --- |
|
|
12
|
+
| Native Switch `value` / `defaultValue` / `onValueChange` | `checked` / `defaultChecked` / `onCheckedChange` |
|
|
13
|
+
| Native Button·Tag `label` | `children` |
|
|
14
|
+
| Native IconButton `icon`, 접근성 이름용 `accessibilityLabel`, `link` tone | `children`, `label`, `ghost` tone |
|
|
15
|
+
| Native Image `source`, `LegacyImageRenderProps`, adapter `legacySource` | `src`·`width`·`height`, `ImageRenderProps`, `sourceAdapter` |
|
|
16
|
+
| Native ToastRegionController `show` | `publish` |
|
|
17
|
+
| Native RadioGroup·SegmentedControl `options`와 Option 타입 | `items`와 Item 타입 |
|
|
18
|
+
| Native Tabs `options`, TabOption `value` | `items`, TabItem `id` |
|
|
19
|
+
| Native Select `options`, `value`, `defaultValue`, `onValueChange`, SelectOption | `items`/`sections`/`source`, `selectedKey`, `defaultSelectedKey`, `onSelectionChange`, CollectionItemDescriptor |
|
|
20
|
+
| Native Menu item `value`·`icon`·`accessibilityHint`, `onSelect` | `id`, `renderLeading`, `description`, `onAction` |
|
|
21
|
+
| Web Menu·MenuMorph item `onSelect` | 컴포넌트 `onAction(id)` |
|
|
22
|
+
| Web/Native Tabs와 Web Select leading `glyphSize` | `size` |
|
|
23
|
+
| Native Stack `direction`, Grid `descriptor` | `axis`, 직접 `columns`·`gap`·`minColumnWidth` |
|
|
24
|
+
| Native Surface `brand` tone, 숫자 padding/radius | `accent` tone, spacing/radius 토큰 |
|
|
25
|
+
| Native Layout `skipLinkLabel` | 삭제: Web 전용 속성 |
|
|
26
|
+
| Native 입력 `supportText`, ListRow `badge` | `description`, `titleMetadata` |
|
|
27
|
+
| Native Button `style`·`labelStyle`, Surface/Card·Field·AuthScreenLayout·Chip·ListRow·LoadMore `style` | 배치만 `layoutStyle`, 시각 값은 semantic props/recipe |
|
|
28
|
+
| Native 입력 `inputStyle`·`containerStyle`, Image `containerStyle`, Section `titleStyle`·`descriptionStyle` | 배치는 `layoutStyle`, 입력 크기는 `size`, 문구는 typography recipe |
|
|
29
|
+
| Contracts `validateLayoutDescriptor` | `validateLayoutWebDescriptor` 또는 `validateLayoutRegions` |
|
|
30
|
+
| Catalog summary `fullyPreviewable`·`partiallyPreviewable`·`contractOnly` | `fullyMature`·`partiallyMature`·`plannedOnly` |
|
|
31
|
+
| Native Progress `max` 기본값 1(분수) — **1.12.0** | 기본값 100(`progressRecipe.defaults.max`, Web과 동일). 분수를 넘기던 곳은 백분율로 바꾸거나 `max={1}`을 명시한다. 2026-10-02 사용자가 1.11과 같은 방식(관리 소비 앱 전수 이관, minor)으로 릴리스를 지시했다. 확인한 소비처: BurnTok `ProductRenderers.stories.tsx`의 `value={0.64}` |
|
|
32
|
+
|
|
33
|
+
Select의 `onSelectionChange`에는 선택 해제를 뜻하는 null이 올 수 있다. 이전 비-null
|
|
34
|
+
handler를 이관할 때는 null 처리 방침을 제품에서 명시한다. 메뉴의 실행과 선택 상태 변경은
|
|
35
|
+
각각 `onAction`과 `selection.onSelectionChange`로 구분한다. 항목별 실행 콜백을 섞지 않는다.
|
|
36
|
+
|
|
37
|
+
Image의 `sourceAdapter(descriptor)`는 유지한다. 인증 header·캐시 옵션이 있는 RN source나
|
|
38
|
+
번들 자산은 이 경계로 넘기되 실제 크기와 canonical src를 제공한다. 이미지 크기를 임의로
|
|
39
|
+
추정하지 않는다. React Native 자체의 Image·Switch API는 HJM 이관 대상이 아니다.
|
|
40
|
+
|
|
41
|
+
## 스타일 경계
|
|
42
|
+
|
|
43
|
+
제거 대상은 위 표에 열거한 deprecated 공개 통로다. 플랫폼 host의 정식 `style`,
|
|
44
|
+
renderer에 주입하는 이미지 스타일, 제품 소유 슬롯과 private recipe 스타일까지 일괄 삭제하는
|
|
45
|
+
변경은 아니다. 배치에 paint 값을 넣어 타입을 우회하지 않는다. FloatingActionButton과
|
|
46
|
+
LoadMore의 내부 Button 조합은 비공개 RecipeButton을 써서 recipe의 크기·색·그림자를 보존한다.
|
|
47
|
+
해당 구현을 패키지 entry에서 export하지 않는다.
|
|
48
|
+
|
|
49
|
+
## 관리 소비 저장소
|
|
50
|
+
|
|
51
|
+
번뚝·다에리·비행중·모펀의 직접 호출과 제품 래퍼를 함께 이관한다. 스핀트·유틸버스·포트폴리오
|
|
52
|
+
사이트·App Release Hub도 새 공개 타입으로 검사한다. 웹과 앱이 있는 제품은 양쪽을 확인한다.
|
|
53
|
+
소스 검사, 새 패키지 설치/lock 갱신, 기기 검증, npm 게시·운영 배포는 별개의 단계다.
|
|
54
|
+
로컬 후보 선언을 연결한 검사만으로 게시된 1.11 소비 설치를 주장하지 않는다.
|
|
55
|
+
|
|
56
|
+
## Storybook
|
|
57
|
+
|
|
58
|
+
Web/Native 프로필 편집은 기본·어두운 테마·큰 글자를 유지한다. 중복 Playground 링크는
|
|
59
|
+
`patterns-profile-studio--default`로 바꾼다. Web showcase 색상 변수는 `--hjm-color-*`만 쓴다.
|
|
60
|
+
이 내부 변수 이관은 공개 renderer CSS 토큰 변경이 아니다. 모든 예제는 위 canonical API로 갱신한다.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# NavigationBar — 글래스 네비게이션 바
|
|
2
|
+
|
|
3
|
+
검토일: 2026-10-01
|
|
4
|
+
|
|
5
|
+
`NavigationBar`는 브랜드·탐색·검색/계정 행동을 배치하는 상단 탐색 조합입니다.
|
|
6
|
+
`@hjmds/react/navigation-bar`, `@hjmds/react-native/navigation-bar`에서 가져옵니다.
|
|
7
|
+
|
|
8
|
+
```tsx
|
|
9
|
+
<NavigationBar label="사이트 탐색" brand={<Text>브랜드</Text>} actions={<SearchField /* 제품의 현지화된 필드 props */ />}>
|
|
10
|
+
{/* 제품의 Link, Menu, Button 등 탐색 항목 */}
|
|
11
|
+
</NavigationBar>
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
- 필수 `label`, `brand`, `children`, 선택 `actions` 슬롯을 받습니다.
|
|
15
|
+
- Web은 이름이 있는 nav와 줄바꿈되는 세 슬롯, Native는 큰 글씨에서도 늘어나는 두 행입니다.
|
|
16
|
+
- Web은 배경 흐림이 지원되면 92% 불투명 semantic surface와 blur를 사용합니다.
|
|
17
|
+
미지원/투명도 줄이기/강제 색상에서는 불투명 배경을 유지합니다.
|
|
18
|
+
- Native는 core renderer에 필수 blur 의존성을 추가하지 않고 불투명 semantic surface로
|
|
19
|
+
대체합니다. 실제 iOS 유리 굴절 효과를 구현했다고 주장하지 않습니다.
|
|
20
|
+
- 메뉴의 초점·키보드·닫힘과 검색/계정 상태는 기존 Menu/SearchField 및 제품이 소유합니다.
|
|
21
|
+
슬롯을 하나의 접근성 요소로 합치지 않습니다. 브랜드/목적지는 앱에서 Link로 전달할 수 있습니다.
|
|
22
|
+
- `TopBar`는 화면 제목·뒤로가기·소수 행동을 위한 chrome, `BottomNavigation`은 최상위 route,
|
|
23
|
+
`NavigationBar`는 사이트 탐색의 다중 슬롯 조합입니다. 같은 선택 상태를 중복 보관하지 않습니다.
|
|
24
|
+
|
|
25
|
+
근거: 사용자가 제공한 [Glassy Navbar 릴](https://www.instagram.com/reel/Dd8_OYaTwmG/)의
|
|
26
|
+
브랜드·드롭다운·검색·계정 배치를 관찰해 독립 구현했습니다. 원본 소스/에셋은 가져오지 않았습니다.
|
|
27
|
+
Storybook: **컴포넌트 → 탐색 → 글래스 네비게이션 바**, Default/Dark/LargeText.
|
|
28
|
+
구현·검증 기록은 [같은 변경의 증거](../../../docs/evidence/navigation-references-2026-10-01/README.md)를 따릅니다.
|
|
@@ -93,7 +93,7 @@ Expo Go cannot verify these linked native modules.
|
|
|
93
93
|
|
|
94
94
|
## Evidence and promotion
|
|
95
95
|
|
|
96
|
-
Web stories:
|
|
96
|
+
Web stories: 갤러리/모션 연동. Native stories: 실험실/선택적 연동.
|
|
97
97
|
Tests cover adaptation logic and web browser behavior; native mocks cannot prove OS gestures,
|
|
98
98
|
keyboard animation, accessibility focus, native linking or installed-device health. Keep native
|
|
99
99
|
adapters experimental until iOS/Android device evidence exists. No consumer migration or publication
|
|
@@ -124,3 +124,26 @@ product image/menu behavior and removes the matching peers. There is no persiste
|
|
|
124
124
|
reports transitive UI packages expecting Storybook 10.6 and safe-area-context 5.8 versus 5.7.
|
|
125
125
|
Builds passing do not erase these warnings or prove device compatibility.
|
|
126
126
|
- No npm publication, consumer migration, native binary build, commit or push was performed.
|
|
127
|
+
|
|
128
|
+
## Shared behavior after the component overlap audit
|
|
129
|
+
|
|
130
|
+
The 2026-10-01 audit found independent typeahead policies in Menu, MorphingMenu and ContextMenu.
|
|
131
|
+
Their Web item searches now share the base Menu's 500ms reset, declared textValue, circular search
|
|
132
|
+
and repeated-character cycling. Menu opening, OS context-menu behavior and presentation stay host-owned.
|
|
133
|
+
|
|
134
|
+
CarouselMotion now resolves slide IDs, selected/inert state, accessible names and finite navigation
|
|
135
|
+
through the canonical Carousel contract in both renderers. Its optional composeAccessibleName
|
|
136
|
+
accepts the same localized position/name composer as Carousel; omitting it preserves the slide label.
|
|
137
|
+
It remains a controlled swipe/motion presentation without autoplay or uncontrolled defaults.
|
|
138
|
+
|
|
139
|
+
Native Field and built-in text inputs share a recipe-owned label/support/error frame.
|
|
140
|
+
GestureSheetInput retains BottomSheetTextInput's keyboard tracking but now uses the base field's
|
|
141
|
+
input geometry, typography, placeholder and provider font scaling instead of separate constants.
|
|
142
|
+
|
|
143
|
+
## Static Avatar fallback — 2026-10-01
|
|
144
|
+
|
|
145
|
+
Both renderer `/avatar-blobatar` entries now provide `createBlobatarFallback` for
|
|
146
|
+
existing Avatar. They are optional factories, not new canonical components or
|
|
147
|
+
root exports. See the [fallback contract](avatar-fallback.md) for installation,
|
|
148
|
+
source recovery and identity/accessibility rules. This addition does not imply
|
|
149
|
+
that the earlier device evidence covers Blobatar.
|
package/docs/otp-field.md
CHANGED
|
@@ -93,7 +93,7 @@ Backspace → 앞 칸으로)도 이 모델에서는 별도 로직이 필요 없
|
|
|
93
93
|
| 축 | 상태 |
|
|
94
94
|
| --- | --- |
|
|
95
95
|
| `value`(controlled, 하나의 문자열) | 공개 |
|
|
96
|
-
| `availability`(enabled/disabled/readOnly/busy) | 공개 — 서버 인증 중 `busy` |
|
|
96
|
+
| `availability`(enabled/disabled/readOnly/busy) | 공개 — 서버 인증 중 `busy`. Web은 busy를 disabled가 아니라 read-only + `aria-busy`로 표현한다(아래) |
|
|
97
97
|
| `validation`(valid/invalid) | 공개 — 오류 카피는 Field의 `error` 슬롯 |
|
|
98
98
|
| 칸별 포커스·칸별 접근성 발화 | **배제**(의도적) — 위 판정 참고 |
|
|
99
99
|
| 영숫자 문자 집합 | **배제** — 측정된 요구 없음 |
|
|
@@ -102,3 +102,25 @@ Backspace → 앞 칸으로)도 이 모델에서는 별도 로직이 필요 없
|
|
|
102
102
|
|
|
103
103
|
이 조사 당시 제품 채택은 미확인이었다. 2026-09-29부터 제품 채택은 관측으로 분리하며,
|
|
104
104
|
현재 성숙도는 catalog와 [승격 기준](stable-promotion.md)을 따른다.
|
|
105
|
+
|
|
106
|
+
## Presentation options (2026-10-01)
|
|
107
|
+
|
|
108
|
+
Web and Native accept `presentation="boxes" | "underline"`; boxes remains the
|
|
109
|
+
compatible default. Underline removes the side/top slot outlines and keeps a
|
|
110
|
+
strong bottom border with the same focus, filled and error colors. This changes
|
|
111
|
+
only decorative slots: one actual input still owns selection, paste, numeric
|
|
112
|
+
sanitization, SMS autocomplete and the completion callback. Never replace it with
|
|
113
|
+
six separately focused fields to obtain this appearance.
|
|
114
|
+
|
|
115
|
+
Both showcases place the interactive preview under 컴포넌트/입력/OtpField
|
|
116
|
+
with Default, Dark and LargeText. The two presentations share a controlled sample
|
|
117
|
+
value and an explicit error toggle. “Input complete” means six characters entered,
|
|
118
|
+
not a successful server verification. Existing input behavior tests now exercise
|
|
119
|
+
both presentations on Web and Native; actual device autofill remains separate QA.
|
|
120
|
+
|
|
121
|
+
## busy 동안 포커스 유지 (2026-10-02)
|
|
122
|
+
|
|
123
|
+
Web `busy`는 예전에 input을 disabled로 바꿨다. 포커스된 input이 disabled가 되면 브라우저가 포커스를
|
|
124
|
+
`<body>`로 옮겨, 인증 실패 뒤 키보드 사용자가 처음부터 다시 탐색해야 했다(STEA 후보 검토의 인증번호
|
|
125
|
+
구성에서 확인). 이제 busy는 read-only + `aria-busy`이고, 흐린 표시는 FieldFrame이 그대로 맡는다.
|
|
126
|
+
Native는 처음부터 `editable={false}`와 `accessibilityState.busy`로 표현해 왔다.
|
package/docs/pagination.md
CHANGED
|
@@ -138,7 +138,7 @@ Steps와 같은 이유다: 순서를 나타내는 문장의 어순과 조사는
|
|
|
138
138
|
필수입니다. 상태·데이터 요청·결과 교체와 URL 동기화는 제품이 소유합니다.
|
|
139
139
|
|
|
140
140
|
2026-09-16 사용자의 명시적 확장 요청으로 라이브러리 beta를 제공하고 제품 채택은 별도로
|
|
141
|
-
추적합니다.
|
|
141
|
+
추적합니다. `갤러리/웹 탐색`에서 125개 로컬 기록의 실제 페이지별 목록과 표시 범위가
|
|
142
142
|
바뀝니다. 서버 요청이나 제품 적용을 검증한 것은 아닙니다.
|
|
143
143
|
|
|
144
144
|
[MUI Pagination](https://mui.com/material-ui/react-pagination/)의 명시적 페이지 탐색과
|
package/docs/popover.md
CHANGED
|
@@ -37,7 +37,7 @@ label/textValue, selection mode)을 따르는 항목 **목록**이고 그 role/k
|
|
|
37
37
|
catalog에 별도 `planned` 항목으로 있는 `ConfirmPopover`(antd `Popconfirm`,
|
|
38
38
|
`relationship: "adapted"`)는 이 Popover 위의 **조합**이다 — Popover의 anchored
|
|
39
39
|
비모달 surface에 되돌릴 수 있는 행동의 확인·취소를 얹은 조합이다. 파괴적 동작은
|
|
40
|
-
AlertDialog를 사용한다.
|
|
40
|
+
AlertDialog를 사용한다. `컴포넌트/오버레이/Popover/ReversibleConfirmation`은 기록 보관·취소가
|
|
41
41
|
작동하는 예제이며 새 독립 renderer 수에 더하지 않는다.
|
|
42
42
|
|
|
43
43
|
## 일반화한 계약
|
|
@@ -142,7 +142,7 @@ Dialog 안의 Popover는 첫 Escape를 소유한다. 내부 Menu가 Escape를
|
|
|
142
142
|
|
|
143
143
|
2026-09-16 사용자의 확장 요청으로 Web beta를 제공했다. 2026-09-29 focus/keyboard·hover/touch·
|
|
144
144
|
320px long-copy browser proof를 확인해 stable로 승격한다. Native는 `unsupported`; 제품 채택은 별도다.
|
|
145
|
-
|
|
145
|
+
`컴포넌트/오버레이/Popover/Filters`는 제목·즐겨찾기 조건 적용/취소/초기화와 실제 목록 교체를 제공한다.
|
|
146
146
|
`ReversibleConfirmation`은 보관 후 취소 버튼으로 초점을 옮기며 실제로 복원한다.
|
|
147
147
|
|
|
148
148
|
[Radix Popover](https://www.radix-ui.com/primitives/docs/components/popover)의 비모달 focus·
|
|
@@ -13,6 +13,13 @@ Native의 외부 배치는 `layoutStyle`, UI 식별은 `testID`를 사용한다.
|
|
|
13
13
|
Web의 상위 앱 셸에 이미 main landmark가 있으면 `as="section"`을 사용한다. 이 옵션은
|
|
14
14
|
다에리 WebShell의 main 안에 로그인 레이아웃을 채택할 때 중첩 main을 피하기 위해 추가했다.
|
|
15
15
|
|
|
16
|
+
2026-10-01 로그인 조합 변경은 [로그인 화면 계약](auth-screen.md)의 mainCard와 pendingLabel을
|
|
17
|
+
사용한다. 제공자 버튼 label은 지역화 카탈로그에서 이름만 남기고, 인증 시작부터 완료·취소·실패까지
|
|
18
|
+
같은 main 내용을 유지한 채 pendingLabel만 켜고 끈다. 기존 제품 카드 wrapper를 제거하고 mainCard로
|
|
19
|
+
옮기면 배경까지 유지된다. 버튼마다 busy를 켜는 기존 연결은 이 카드 상태로 옮긴다.
|
|
20
|
+
HJM npm 게시만으로 이 변경이 제품에 자동 적용되지는 않는다. exact dependency·lock·계약을
|
|
21
|
+
업데이트하고 제품의 상태 연결과 문구를 바꾼 뒤 웹·앱을 함께 검증한다.
|
|
22
|
+
|
|
16
23
|
## 설정 한 행
|
|
17
24
|
|
|
18
25
|
`Switch presentation="row"`에 label/description/checked/onCheckedChange를 전달하면 행 전체가
|
|
@@ -54,7 +54,7 @@ Yajalal과 Choose Window의 현재 제품은 Flutter이므로 JS renderer 소비
|
|
|
54
54
|
dark/long-copy/large-text/rtl 환경으로 직접 실행한다.
|
|
55
55
|
- Showcase 격리: `packages/react/test/showcase-style-isolation.browser.test.tsx`.
|
|
56
56
|
SSR class 확인만으로 발견되지 않은 Tabs 가로 배치와 버튼 모양을 실제 browser로 검사한다.
|
|
57
|
-
- Review:
|
|
57
|
+
- Review: `패턴/토스트 배치`, 기존 Button/IconButton/Tabs/Notice story.
|
|
58
58
|
- Toast는 1280px 창의 420px 카드에서도 액션 행을 유지한다. 창 breakpoint만으로 판단하면
|
|
59
59
|
실제 provider의 좁은 카드에서 큰 글자 버튼이 다시 압축되므로 grid를 카드 기본 구조로 둔다.
|
|
60
60
|
- NativeProvider: `packages/react/test/native-provider-hydration.browser.test.tsx`5개와
|
package/docs/progress.md
CHANGED
|
@@ -14,3 +14,11 @@
|
|
|
14
14
|
|
|
15
15
|
**Native**는 conic gradient가 없어 회전한 반링으로 그린다. 그림을 위해 의존성을 들이지
|
|
16
16
|
않는다 — 값은 wrapper가 발표하므로 이 도형은 장식이다.
|
|
17
|
+
|
|
18
|
+
## max 기본값 통일 (2026-10-02)
|
|
19
|
+
|
|
20
|
+
`max`를 생략하면 두 renderer 모두 `progressRecipe.defaults.max`(100)를 쓴다. 그 전에는 Web 100,
|
|
21
|
+
Native 1이라 같은 `value={76}`이 Web에서는 76%, Native에서는 RangeError였다(STEA 후보 검토의
|
|
22
|
+
수치 요약 구성을 Native 시뮬레이터에서 띄우다 발견). 100을 고른 이유는 Web 기존 동작과 문서 예제가
|
|
23
|
+
백분율이기 때문이다. 0–1 분수가 자연스러운 곳(UploadItem의 업로드 비율)은 `max={1}`을 쓰거나
|
|
24
|
+
백분율로 바꿔 넘긴다. Native 기본값이 바뀌는 호환 파괴 변경이지만, 1.11.0과 같이 사용자가 관리 소비 앱 전수 이관을 결정해 1.12.0 minor에 싣고 이관표에 기록했다.
|
package/docs/provider-button.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# AuthProviderButton contract
|
|
2
2
|
|
|
3
|
-
**문제.**
|
|
3
|
+
**문제.** 제공자 브랜드 규정을 따르는 소셜 로그인 버튼. BurnTok이
|
|
4
4
|
`.hjm-button.bt-provider-google` 네 줄로 HJM 버튼을 덮어 쓰던 자리다.
|
|
5
5
|
|
|
6
6
|
**왜 Button의 tone이 아닌가.** HJM의 tone은 **의미**다 — primary/secondary/danger는
|
|
@@ -26,8 +26,15 @@
|
|
|
26
26
|
**포커스 링은 바깥에 그린다.** `#FEE500`부터 `#000000`까지 어떤 배경 위에서도 보여야
|
|
27
27
|
하므로 `focusOutlineOffset`으로 fill 밖에 둔다.
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
**로그인 화면의 진행 상태는 카드가 소유한다.** 2026-10-01 사용자 요청으로 로그인 조합은
|
|
30
|
+
`AuthScreenLayout`의 pendingLabel을 사용한다. 모든 제공자 버튼을 숨기고 기존 카드 크기에서
|
|
31
|
+
중앙 로딩 하나만 보여 준다([로그인 화면 계약](auth-screen.md)). 버튼 label은 제품이 제공자
|
|
32
|
+
이름만 전달한다. 이전 버전 소비와 단독 버튼의 호환성을 위해 descriptor.busy는 유지하며,
|
|
33
|
+
카드 진행 상태와 동시에 사용하지 않는다.
|
|
34
|
+
단독 버튼이 busy이면 로고와 글자는 자리를 유지한 채 시각적으로 숨기고 카드 중앙에
|
|
35
|
+
스피너 하나만 보인다. 버튼의 접근성 이름과 높이·폭은 유지한다. 2026-10-02 사용자 요청으로
|
|
36
|
+
기존의 글자 옆 스피너 표현을 제거했다. 소셜 버튼마다 글자와 스피너를 나란히 두는 대안은
|
|
37
|
+
로딩 중 시선이 분산되고 버튼 폭도 달라져 채택하지 않았다.
|
|
31
38
|
|
|
32
39
|
**값의 출처.** 각 제공자의 공개 브랜드 가이드라인(2026-09 확인). 가이드라인이 바뀌면
|
|
33
40
|
`authProviderPalettes` 한 곳만 고친다.
|
package/docs/rating.md
CHANGED
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
|
|
66
66
|
## 2026-09-16: React/RN 작동 조합
|
|
67
67
|
|
|
68
|
-
명시 요청에 따라
|
|
68
|
+
명시 요청에 따라 `컴포넌트/입력/Rating`에 정수/0.5점 입력과 읽기 전용 평균 표시를 추가했다.
|
|
69
69
|
입력은 기존 Slider, 현재값과 평균 표시는 Statistic이며 별 모양 variant를 새로 만든 것은 아니다.
|
|
70
70
|
|
|
71
71
|
- [Web 예제](../../../showcase/web/src/patterns/Rating.stories.tsx): `@hjmds/react/slider`,
|
|
@@ -113,9 +113,9 @@ Context 배선/정적 토큰 사용은 예제로 설명하며 BorderBeam은 모
|
|
|
113
113
|
경로를 유지했다. Anchor는 문서·별도 스크롤 영역, section focus, reduced motion, fragment
|
|
114
114
|
history와 동적 본문 관찰을 구현했다. Web 전용이며 Native wrapper를 추가하지 않았다.
|
|
115
115
|
[Breadcrumb](./breadcrumb.md), [Pagination](./pagination.md), [Anchor](./anchor.md).
|
|
116
|
-
-
|
|
116
|
+
- 갤러리/웹 탐색은 125개 기록의 페이지별 목록 교체와 보관함 왕복을 제공한다.
|
|
117
117
|
경로 변경 후 사라진 링크 대신 새 본문으로 focus를 옮기며 초기 mount에서는 focus를 뺏지 않는다.
|
|
118
|
-
|
|
118
|
+
컴포넌트/탐색/Anchor는 세 부분의 실제 읽기 가이드에서 목차·스크롤·focus를 연결한다.
|
|
119
119
|
- 탐색 묶음 `pnpm ci:check` exit 0: contracts 733, Web SSR 139 + browser 140,
|
|
120
120
|
Native 268 = 패키지 테스트 1,280개. Showcase Web 19 / Native 1과 타입·문서·evidence·
|
|
121
121
|
번들·정적 Storybook(Web 71 / contract-only 23 / unsupported 0)이 통과했다.
|
|
@@ -131,7 +131,7 @@ Context 배선/정적 토큰 사용은 예제로 설명하며 BorderBeam은 모
|
|
|
131
131
|
바깥 pointer/Tab이 향한 곳을 그대로 두고, 자식 popover가 감싸는 Dialog보다 Escape를 먼저 받는다.
|
|
132
132
|
[API와 근거](./popover.md). ConfirmPopover는 새 renderer가 아니라 Popover의 확인/취소 조합으로
|
|
133
133
|
제공하고 파괴적 동작은 AlertDialog에 남긴다. [조합 근거](./confirm-popover.md).
|
|
134
|
-
-
|
|
134
|
+
- 컴포넌트/오버레이/Popover는 필터 적용과 되돌릴 수 있는 보관 두 화면을 제공한다. 보관하면 트리거가
|
|
135
135
|
사라지므로 제품이 초점을 보관 취소 버튼으로 옮기고, 초기 mount에서는 초점을 뺏지 않는다.
|
|
136
136
|
- 묶음 종료 시 두 예산이 실측에서 걸려 근거와 함께 올렸다. contracts 루트 barrel은
|
|
137
137
|
111.8 -> 112.3 kB gzip인데 모듈별로 재면 catalog.js +522 B(Popover·ConfirmPopover maturity
|
|
@@ -160,7 +160,7 @@ Context 배선/정적 토큰 사용은 예제로 설명하며 BorderBeam은 모
|
|
|
160
160
|
- 브라우저(chromium) 검증 6개: 도킹·초점 가둠·스크롤 락과 flush 모서리, RTL `start` 미러링과
|
|
161
161
|
wide 560px, 비모달의 살아 있는 페이지·내부 Escape만 dismiss, 사유별 단일 보고와 busy 중
|
|
162
162
|
outside 차단, controlled owner의 busy 종료와 1회 완료, 320px·2배 글자에서 가로 넘침 없음.
|
|
163
|
-
|
|
163
|
+
`컴포넌트/오버레이/Side Panel`은 기록 편집(모달)과 도움말(비모달) 두 화면을 제공한다.
|
|
164
164
|
- 예산은 실측으로 넷을 조정했다. `./side-panel` 45.9 kB raw / 11.0 kB gzip(6 modules),
|
|
165
165
|
`./overlays`는 modal.js 분리로 6→7 modules(81.2/16.7 kB, 의존성 추가 아님),
|
|
166
166
|
루트는 36→38 modules(322.3/66.3 kB, 바이트 한도 그대로), `./styles.css`는 도킹·크기·footer
|
package/docs/screen-chrome.md
CHANGED
|
@@ -27,7 +27,7 @@ Web의 headingLevel은 페이지 구조가 정한다. div root이므로 Dialog
|
|
|
27
27
|
큰 글자에서는 제목을 다음 행으로 내려 행동과 겹치지 않게 한다.
|
|
28
28
|
|
|
29
29
|
BottomCTA는 primaryAction 하나와 선택적인 secondaryAction, description을 받는다.
|
|
30
|
-
loading은 표시
|
|
30
|
+
loading은 표시 문구를 시각적으로 숨기되 원래 폭과 접근성 이름을 유지하고 중복 실행을 막는다. 큰 글자에서 세로로 쌓을 때
|
|
31
31
|
가로 배치용 flex-basis를 해제한다. 가로 배치 값이 세로 높이로 해석되어 거대한 공백을
|
|
32
32
|
만들었던 320px 브라우저 재현이 근거다. 간격은 Native와 같은 `bottomCtaRecipe.gap`이다.
|
|
33
33
|
|
|
@@ -43,7 +43,7 @@ LTR/RTL, light/dark에서 hit target, 글자 범위, overflow, 제목 분리와
|
|
|
43
43
|
검증한다. ref/heading/link, busy 중 중복 실행 방지와 폭/focus 보존, sticky footer 위
|
|
44
44
|
마지막 본문 행동의 도달 가능성도 검사한다. 기본 SSR renderer fixture를 추가한다.
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
`패턴/알림 설정`는 Web/RN에서 동일 문구·선택·저장 상태를 합성한다.
|
|
47
47
|
행 제목과 스위치 문구가 중복되면 `labelVisibility="hidden"`을 사용한다. `label`은
|
|
48
48
|
계속 필수이며 Web의 visually-hidden 텍스트와 Native의 accessibilityLabel로 남는다.
|
|
49
49
|
Web List의 indented 구분선은 행 margin이 아닌 별도 선으로 그린다. 320px 조합에서
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Scroll progress
|
|
2
|
+
|
|
3
|
+
Reviewed: 2026-10-01. Both renderers expose `ScrollProgress` through `/scroll-progress`.
|
|
4
|
+
This extension composes canonical Progress; it does not introduce another range,
|
|
5
|
+
accessibility or drawing implementation. Use plain Progress for task completion.
|
|
6
|
+
|
|
7
|
+
Pass `label`, `metrics: {offset, contentSize, viewportSize}` and normal Progress
|
|
8
|
+
presentation options. Metrics are logical forward distances in one consistent unit.
|
|
9
|
+
The shared resolver clamps bounce/overscroll into 0–1. An unmeasured viewport returns
|
|
10
|
+
0; content fitting a measured viewport returns 1. Negative sizes and nonfinite
|
|
11
|
+
numbers throw. Horizontal RTL hosts must normalize platform-specific offsets.
|
|
12
|
+
|
|
13
|
+
On Web use `const metrics = useScrollMetrics(host)` with the actual vertical
|
|
14
|
+
scrolling HTMLElement stored by a callback ref. No implicit window listener is
|
|
15
|
+
installed. Scroll events are batched per animation frame; ResizeObserver and DOM
|
|
16
|
+
changes update the content extent. The hook disconnects when the host changes.
|
|
17
|
+
|
|
18
|
+
On Native feed `onScroll` contentOffset.y, `onContentSizeChange` height, and
|
|
19
|
+
`onLayout` viewport height from the product's ScrollView. Keep the product's
|
|
20
|
+
existing callbacks and gesture handling. The renderer adds no scroll responder.
|
|
21
|
+
Both showcases contain `컴포넌트/피드백/Scroll Progress` with working scroll
|
|
22
|
+
content. Updates are continuous range values, not repeated live announcements.
|
|
23
|
+
|
|
24
|
+
Regression checks cover overscroll, unknown/fitting dimensions, actual browser
|
|
25
|
+
scroll/content resize and Native canonical Progress values. The [Native integration audit](../../../docs/evidence/native-visual-integration-2026-10-01/README.md)
|
|
26
|
+
records Default/Dark/LargeText initial-view captures on the existing iPhone 17 / iOS 27
|
|
27
|
+
simulator. The subsequent [component flow audit](../../../docs/evidence/component-flows-2026-10-01/README.md)
|
|
28
|
+
verifies real LargeText swipes from 0% to 100% and back to 87%, with captures and
|
|
29
|
+
accessibility snapshots. VoiceOver speech and physical-device performance remain unverified.
|
package/docs/sheet.md
CHANGED
|
@@ -61,3 +61,5 @@ focus/dismiss와 텍스트 배치 회귀를 직접 확인하도록 위 테스트
|
|
|
61
61
|
|
|
62
62
|
참조: [React Native Keyboard](https://reactnative.dev/docs/keyboard),
|
|
63
63
|
[ScrollView](https://reactnative.dev/docs/scrollview).
|
|
64
|
+
|
|
65
|
+
Native accessibility follow-up (2026-10-01): at 200% text scale, the close glyph was clipped inside the fixed IconButton frame. Dialog and Sheet now render that decorative glyph at a fixed icon size, matching Toast; title/body text still scales and the named close action and touch target are preserved. `sheet-viewport.test.tsx` checks both renderers and close callbacks.
|
package/docs/sidebar.md
CHANGED
|
@@ -31,3 +31,9 @@
|
|
|
31
31
|
|
|
32
32
|
**Web 전용.** 폰은 BottomNavigation을 쓰고, 네이티브 태블릿의 split view는 navigator의
|
|
33
33
|
문제다.
|
|
34
|
+
|
|
35
|
+
## 선택형 Web 표현 — 2026-10-01
|
|
36
|
+
|
|
37
|
+
`appearance`는 standard(기본), bounce, hook, proximity를 지원한다. bounce는 새로 선택한 항목의 아이콘에 한 번만 적용하고, hook은 선택 항목의 시작 쪽 곡선 경계를 강조한다. proximity는 마우스/펜의 세로 거리에 따라 아이콘만 최대 18% 확대한다. 링크 경계와 키보드 순서는 변하지 않는다. 터치는 근접 효과를 만들지 않는다. HJM provider의 모션 줄이기에서 동적 표현을 끄며, provider 없이도 기본 정적 탐색은 가능하다.
|
|
38
|
+
|
|
39
|
+
독립적으로 구현한 제한된 표현이다. 원본 사이트의 모션 엔진을 복제하지 않았다. Web 전용이라는 기존 지원 범위를 유지하며 Native에서 새 사이드바를 만들지 않는다. Storybook `컴포넌트/탐색/Sidebar Motion`의 Default/Dark/LargeText에서 네 가지 표현과 접기를 비교한다. 기존 앱 셸 예제는 컴포넌트/탐색/Sidebar에 남는다.
|
package/docs/splitter.md
CHANGED
|
@@ -69,7 +69,7 @@ Native `unsupported`다. 제품 채택과 실제 보조기기 실측은 승격
|
|
|
69
69
|
인자 평가까지 통째로 건너뛰어 키보드 조절이 조용히 죽는다. commit을 먼저 하고 알린다.
|
|
70
70
|
- 로컬 검증: `test/splitter.browser.test.tsx` 6개(separator 의미·수직 방향과 44px hit
|
|
71
71
|
target, 방향키 step과 Home/End 경계, 드래그 스냅과 드래그당 1회 end, RTL 드래그·키보드,
|
|
72
|
-
disabled, 실제 Tab focus와 focused keyboard resize)와
|
|
72
|
+
disabled, 실제 Tab focus와 focused keyboard resize)와 `컴포넌트/레이아웃/Splitter`.
|
|
73
73
|
|
|
74
74
|
**검증 범위.** Web Chromium renderer matrix가 긴 pane 콘텐츠·환경·접근성 증거를 제공한다.
|
|
75
75
|
제품 vertical slice, screen reader 실측, 모든 OS 조합은 보증하지 않으며 소비 앱 릴리스 QA에서 확인한다.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# StepPlayer
|
|
2
|
+
|
|
3
|
+
검토일: 2026-10-01.
|
|
4
|
+
|
|
5
|
+
`@hjmds/react/step-player`, `@hjmds/react-native/step-player`는 기존 Steps, Progress, Button을 합성한다. 별도 단계 상태 머신이나 재생 엔진을 두지 않는다. 사용자가 요청한 단계형 소개와 미디어는 서로 다른 시계를 사용하므로 호스트가 현재 위치와 재생 상태를 소유한다.
|
|
6
|
+
|
|
7
|
+
- `descriptor`, `statusLabels`, `composeAccessibleName`: 기존 Steps 계약 그대로.
|
|
8
|
+
- `progress`: 전체 재생 진행률 0~1. `playing`: 실제 호스트 재생 여부.
|
|
9
|
+
- `onPlayingChange`: 재생/일시정지 요청. 콜백 호출 자체로 내부 상태를 바꾸지 않는다.
|
|
10
|
+
- `onReplay`: 호스트가 현재 단계와 진행률을 초기화하고 재생 정책을 결정한다.
|
|
11
|
+
- `labels`: 번역된 play/pause/replay/progress 문구. `disabled`는 두 동작을 비활성화한다.
|
|
12
|
+
- `children`: 현재 단계의 실제 콘텐츠. 모션은 기존 ContentTransition 등으로 합성한다.
|
|
13
|
+
|
|
14
|
+
완료 시 마지막 단계와 progress=1을 전달하고 재생 여부를 false로 바꾼다. 실제 비동기 작업의 완료를 타이머로 추정하는 용도가 아니다. 재생 종료/탐색 이탈/백그라운드 정지는 호스트 책임이다. 모션 줄이기는 콘텐츠 전환을 줄이며 사용자가 요청한 재생 자체를 막지 않는다.
|
|
15
|
+
|
|
16
|
+
양쪽 Storybook `컴포넌트/피드백/Step Player`에 Default/Dark/LargeText를 제공한다. 예제만 사용자가 시작하는 6초 소개 시계를 가지며, 브라우저 숨김 또는 Native AppState 비활성에서 정지한다. 실제 서비스의 작업 진행이나 저장 완료를 주장하지 않는다.
|
package/docs/steps.md
CHANGED
|
@@ -21,12 +21,12 @@
|
|
|
21
21
|
|
|
22
22
|
로드맵의 공통 상태 축 표에는 `pending/current/complete/error`가 없다 — Steps 전용 축이다.
|
|
23
23
|
각 step은 이 네 값 중 하나만 가지지만, **제품이 각 step에 개별 status를 배열로 넘기지
|
|
24
|
-
않는다.** 대신 하나의 `currentStepId`(+ 선택적 `currentStepStatus: "current" | "error"`)만
|
|
24
|
+
않는다.** 대신 하나의 `currentStepId`(+ 선택적 `currentStepStatus: "current" | "error" | "complete"`)만
|
|
25
25
|
받고, `resolveStepsDescriptor`가 배열 위치로 나머지를 유도한다.
|
|
26
26
|
|
|
27
27
|
```
|
|
28
28
|
index < cursor → complete
|
|
29
|
-
index === cursor → currentStepStatus (기본 "current", 실패 시 "error")
|
|
29
|
+
index === cursor → currentStepStatus (기본 "current", 실패 시 "error", 끝나면 "complete")
|
|
30
30
|
index > cursor → pending
|
|
31
31
|
```
|
|
32
32
|
|
|
@@ -36,6 +36,11 @@ index > cursor → pending
|
|
|
36
36
|
조합을 타입과 유도 규칙으로 만들 수 없게 한다. clickable을 공개하지 않기로 했으므로(아래
|
|
37
37
|
참고) 흐름은 항상 cursor 기준 선형이라 이 유도가 항상 맞다.
|
|
38
38
|
|
|
39
|
+
`"complete"`는 2026-10-02에 추가했다. 그 전에는 마지막 단계에 커서가 있으면 항상 "진행 중"으로
|
|
40
|
+
읽혀 끝난 흐름을 표현할 수 없었고, STEA 후보 검토의 주문 처리 구성은 끝나면 Steps를 `Result`로
|
|
41
|
+
바꿔 우회했다. cursor를 `"complete"`로 두면 cursor까지 완료, 그 뒤는 pending이라 위 선형 유도를
|
|
42
|
+
깨지 않는다. 마지막 step에서 쓰면 전체 완료다. step별 status 배열은 여전히 받지 않는다.
|
|
43
|
+
|
|
39
44
|
### 순서를 접근성 이름에 남긴다
|
|
40
45
|
|
|
41
46
|
마커가 숫자를 시각적으로만 보여주면(원 안의 "2") 화면낭독기는 라벨만 읽고 몇 번째인지
|
|
@@ -77,7 +82,8 @@ index > cursor → pending
|
|
|
77
82
|
|
|
78
83
|
## 플랫폼 번역
|
|
79
84
|
|
|
80
|
-
- Web: cursor step
|
|
85
|
+
- Web: cursor step이 `"current" | "error"`일 때만 `aria-current="step"`을 단다. cursor가
|
|
86
|
+
`"complete"`면 진행 중인 단계가 없으므로 `aria-current`를 달지 않는다.
|
|
81
87
|
마커 아이콘은 decorative(숨김)로 두고 root의 accessible name은 `accessibleName`
|
|
82
88
|
하나다. `statusLabel`은 visually-hidden 텍스트 또는 `aria-describedby`로 덧붙인다.
|
|
83
89
|
connector는 `aria-hidden`.
|