@iyulab/modern-app 0.16.0 → 0.17.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,21 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.17.0] - 2026-08-11
4
+
5
+ ### Added
6
+
7
+ - **`/react` subpath**, wrapping `SidebarLayout` and `Wizard` with `@lit/react`'s
8
+ `createComponent`. `Wizard` is the only component that dispatches a custom event
9
+ (`step-change`) — a raw custom element in JSX maps an `onStepChange` prop to a listener
10
+ for a literal `"StepChange"` DOM event, which `Wizard` never fires, so the event never
11
+ reaches a consumer without this wrapper. Both components also carry object/array
12
+ properties (`config`, `steps`) that a raw custom element handles correctly under React 19
13
+ (which assigns matching properties directly) but not under React 18 (where non-primitive
14
+ JSX attributes stringify) — the wrapper keeps that working on both. Every component in
15
+ this package (not just these two) also inherits an object-typed `styles` property from its
16
+ base class for part-level style overrides; on React 18 that still needs a ref without a
17
+ wrapper.
18
+
3
19
  ## [0.16.0] - 2026-08-11
4
20
 
5
21
  ### Changed
package/README.md CHANGED
@@ -173,6 +173,38 @@ await app.load({
173
173
  - `hasPermission` 미지정 시 필터링하지 않는다(모든 항목 표시 — 하위호환).
174
174
  - 순수 헬퍼 `filterSidebarItems(items, hasPermission)` 를 직접 재사용할 수도 있다.
175
175
 
176
+ ## React
177
+
178
+ A `@lit/react`-based wrapper for `SidebarLayout` and `Wizard` is available under `/react`.
179
+ Every other exported component works as a plain custom element in JSX; these two specifically
180
+ need the wrapper because `Wizard` dispatches a `step-change` custom event (a raw element maps
181
+ `onStepChange` to a literal `"StepChange"` DOM event it never fires) and both carry object/array
182
+ properties that a raw element only handles correctly under React 19.
183
+
184
+ `@lit/react` and `react` are optional peer dependencies — install them to use this subpath:
185
+
186
+ ```bash
187
+ npm install @iyulab/modern-app @lit/react react
188
+ ```
189
+
190
+ ```tsx
191
+ import { SidebarLayout, Wizard, type SidebarItem, type WizardStep } from '@iyulab/modern-app/react';
192
+
193
+ const main: SidebarItem[] = [{ type: 'link', label: 'Home', href: '/' }];
194
+ const steps: WizardStep[] = [{ id: 'info', label: 'Info' }, { id: 'review', label: 'Review' }];
195
+
196
+ export function App() {
197
+ return (
198
+ <SidebarLayout config={{ type: 'sidebar', title: 'My App', main }}>
199
+ <Wizard steps={steps} active={0} onStepChange={(e) => console.log(e.detail)}>
200
+ <section>Info panel</section>
201
+ <section>Review panel</section>
202
+ </Wizard>
203
+ </SidebarLayout>
204
+ );
205
+ }
206
+ ```
207
+
176
208
  ## Documentation
177
209
 
178
210
  | Guide | Description |
@@ -4,7 +4,7 @@ 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
+ import { formatCurrency as s, formatDate as c, formatNumber as l } from "@iyulab/components/dist/utilities/format.js";
8
8
  //#region src/components/InfoField.ts
9
9
  function u(e) {
10
10
  return e === "up" ? "positive" : e === "down" ? "negative" : "neutral";
@@ -6,6 +6,10 @@ import { SidebarGroupConfig } from '../components/SidebarGroup';
6
6
  import { SidebarButtonConfig } from '../components/SidebarButton';
7
7
  import { SidebarPermissionGuard } from './SidebarPermission';
8
8
  export type { SidebarPermissionGuard } from './SidebarPermission';
9
+ export type { SidebarLinkConfig } from '../components/SidebarLink';
10
+ export type { SidebarSectionConfig } from '../components/SidebarSection';
11
+ export type { SidebarGroupConfig } from '../components/SidebarGroup';
12
+ export type { SidebarButtonConfig } from '../components/SidebarButton';
9
13
  /** 사이드바 레이아웃 컴포넌트의 요소(part) 타입 */
10
14
  export type SidebarParts = 'host' | 'mobile-header' | 'sidebar' | 'sidebar-header' | 'sidebar-main' | 'sidebar-footer' | 'main' | 'progress';
11
15
  /** 사이드바 상태 타입 */
@@ -0,0 +1,25 @@
1
+ import { default as React } from 'react';
2
+ import { EventName } from '@lit/react';
3
+ import { SidebarLayout as SidebarLayoutElement } from './layouts/SidebarLayout.js';
4
+ import { Wizard as WizardElement, WizardStepChangeDetail } from './components/Wizard.js';
5
+ /**
6
+ * React wrapper for `<u-sidebar-layout>`. `config` is an `@property({ type: Object })` —
7
+ * a raw custom element handles that correctly under React 19 (property assignment) but not
8
+ * React 18 (JSX attributes stringify), so this wrapper keeps `config` working on both.
9
+ */
10
+ export declare const SidebarLayout: import('@lit/react').ReactWebComponent<SidebarLayoutElement, {}>;
11
+ export type SidebarLayoutProps = React.ComponentProps<typeof SidebarLayout>;
12
+ /**
13
+ * React wrapper for `<u-wizard>`. `Wizard` dispatches a `step-change` custom event, but a raw
14
+ * custom element in JSX maps `onStepChange` to a listener for a literal `"StepChange"` DOM
15
+ * event — one `Wizard` never fires — so the event never reaches a consumer without this
16
+ * wrapper's `events` mapping. `steps` is also an `@property({ type: Array })`, which the
17
+ * wrapper keeps working on React 18 the same way it does for `SidebarLayout`'s `config`.
18
+ */
19
+ export declare const Wizard: import('@lit/react').ReactWebComponent<WizardElement, {
20
+ onStepChange: EventName<CustomEvent<WizardStepChangeDetail>>;
21
+ }>;
22
+ export type WizardProps = React.ComponentProps<typeof Wizard>;
23
+ export type { SidebarLayoutElement, WizardElement };
24
+ export type { SidebarLayoutConfig, SidebarItem, SidebarLogoConfig, SidebarLinkConfig, SidebarSectionConfig, SidebarGroupConfig, SidebarButtonConfig, SidebarHtmlConfig, } from './layouts/SidebarLayout.types.js';
25
+ export type { WizardStep, WizardStepState, WizardStepChangeDetail } from './components/Wizard.js';
package/dist/react.js ADDED
@@ -0,0 +1,18 @@
1
+ import { Wizard as e } from "./components/Wizard.js";
2
+ import { SidebarLayout as t } from "./layouts/SidebarLayout.js";
3
+ import n from "react";
4
+ import { createComponent as r } from "@lit/react";
5
+ //#region src/react.ts
6
+ var i = r({
7
+ react: n,
8
+ tagName: "u-sidebar-layout",
9
+ elementClass: t,
10
+ events: {}
11
+ }), a = r({
12
+ react: n,
13
+ tagName: "u-wizard",
14
+ elementClass: e,
15
+ events: { onStepChange: "step-change" }
16
+ });
17
+ //#endregion
18
+ export { i as SidebarLayout, a as Wizard };
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.16.0",
4
+ "version": "0.17.0",
5
5
  "keywords": [
6
6
  "iyulab",
7
7
  "web-framework",
@@ -32,13 +32,19 @@
32
32
  "./dist/index.js",
33
33
  "./src/index.ts",
34
34
  "./dist/layouts/*.js",
35
- "./src/layouts/*.ts"
35
+ "./src/layouts/*.ts",
36
+ "./dist/react.js",
37
+ "./src/react.ts"
36
38
  ],
37
39
  "exports": {
38
40
  ".": {
39
41
  "types": "./dist/index.d.ts",
40
42
  "import": "./dist/index.js"
41
43
  },
44
+ "./react": {
45
+ "types": "./dist/react.d.ts",
46
+ "import": "./dist/react.js"
47
+ },
42
48
  "./dist/*": {
43
49
  "types": "./dist/*.d.ts",
44
50
  "import": "./dist/*"
@@ -58,10 +64,27 @@
58
64
  "i18next": "^26.3.6",
59
65
  "lit": "^3.3.3"
60
66
  },
67
+ "peerDependencies": {
68
+ "@lit/react": ">=1.0.8",
69
+ "react": ">=18.0.0"
70
+ },
71
+ "peerDependenciesMeta": {
72
+ "@lit/react": {
73
+ "optional": true
74
+ },
75
+ "react": {
76
+ "optional": true
77
+ }
78
+ },
61
79
  "devDependencies": {
80
+ "@lit/react": "^1.0.8",
62
81
  "@types/node": "^26.1.1",
82
+ "@types/react": "^19.2.14",
83
+ "@types/react-dom": "^19.2.3",
63
84
  "@vitest/browser-playwright": "^4.1.10",
64
85
  "happy-dom": "^20.10.6",
86
+ "react": "^19.2.7",
87
+ "react-dom": "^19.2.7",
65
88
  "typescript": "^5.9.3",
66
89
  "vite": "^8.1.4",
67
90
  "vite-plugin-dts": "^5.0.3",