@designbasekorea/ui-wc 0.13.0 → 0.15.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 +16 -0
- package/LICENSE +21 -0
- package/README.en.md +45 -0
- package/README.md +13 -5
- package/THIRD-PARTY-NOTICES.md +5 -0
- package/dist/esm/components/db-ad-banner.d.ts +6 -0
- package/dist/esm/components/db-ad-banner.js +1 -1
- package/dist/esm/components/db-animation-background.d.ts +7 -0
- package/dist/esm/components/db-animation-background.js +1 -1
- package/dist/esm/components/db-avatar.d.ts +2 -0
- package/dist/esm/components/db-avatar.js +1 -1
- package/dist/esm/components/db-banner.d.ts +2 -0
- package/dist/esm/components/db-banner.js +1 -1
- package/dist/esm/components/db-bottom-navigation.d.ts +2 -0
- package/dist/esm/components/db-bottom-navigation.js +1 -1
- package/dist/esm/components/db-card.d.ts +2 -0
- package/dist/esm/components/db-card.js +1 -1
- package/dist/esm/components/db-carousel.d.ts +2 -0
- package/dist/esm/components/db-carousel.js +1 -1
- package/dist/esm/components/db-code-block.d.ts +3 -0
- package/dist/esm/components/db-code-block.js +1 -1
- package/dist/esm/components/db-color-picker.d.ts +5 -0
- package/dist/esm/components/db-color-picker.js +1 -1
- package/dist/esm/components/db-color-swatch.d.ts +2 -0
- package/dist/esm/components/db-color-swatch.js +1 -1
- package/dist/esm/components/db-confirm.d.ts +2 -0
- package/dist/esm/components/db-confirm.js +1 -1
- package/dist/esm/components/db-context-menu.d.ts +6 -2
- package/dist/esm/components/db-context-menu.js +1 -1
- package/dist/esm/components/db-cookie-banner.d.ts +2 -0
- package/dist/esm/components/db-cookie-banner.js +1 -1
- package/dist/esm/components/db-drawer.d.ts +2 -0
- package/dist/esm/components/db-drawer.js +1 -1
- package/dist/esm/components/db-dropdown.d.ts +2 -0
- package/dist/esm/components/db-dropdown.js +1 -1
- package/dist/esm/components/db-easing-editor.d.ts +5 -0
- package/dist/esm/components/db-empty-state.d.ts +2 -0
- package/dist/esm/components/db-empty-state.js +1 -1
- package/dist/esm/components/db-file-uploader.d.ts +4 -0
- package/dist/esm/components/db-file-uploader.js +1 -1
- package/dist/esm/components/db-footer.d.ts +2 -0
- package/dist/esm/components/db-footer.js +1 -1
- package/dist/esm/components/db-gantt.d.ts +2 -0
- package/dist/esm/components/db-gantt.js +1 -1
- package/dist/esm/components/db-image-list.d.ts +3 -0
- package/dist/esm/components/db-image-list.js +1 -1
- package/dist/esm/components/db-keyframe-editor.d.ts +5 -0
- package/dist/esm/components/db-layer-list.d.ts +71 -0
- package/dist/esm/components/db-layer-list.js +1 -0
- package/dist/esm/components/db-lightbox.d.ts +4 -0
- package/dist/esm/components/db-lightbox.js +1 -1
- package/dist/esm/components/db-list.d.ts +2 -0
- package/dist/esm/components/db-list.js +1 -1
- package/dist/esm/components/db-menu-item.d.ts +2 -0
- package/dist/esm/components/db-menu-item.js +1 -1
- package/dist/esm/components/db-modal.d.ts +3 -0
- package/dist/esm/components/db-modal.js +1 -1
- package/dist/esm/components/db-navbar.d.ts +5 -0
- package/dist/esm/components/db-navbar.js +1 -1
- package/dist/esm/components/db-onboarding-modal.d.ts +3 -0
- package/dist/esm/components/db-onboarding-modal.js +1 -1
- package/dist/esm/components/db-page-header.d.ts +3 -0
- package/dist/esm/components/db-page-header.js +1 -1
- package/dist/esm/components/db-pagination.d.ts +2 -0
- package/dist/esm/components/db-pagination.js +1 -1
- package/dist/esm/components/db-popover.d.ts +2 -0
- package/dist/esm/components/db-popover.js +1 -1
- package/dist/esm/components/db-search-bar.d.ts +3 -0
- package/dist/esm/components/db-search-bar.js +1 -1
- package/dist/esm/components/db-section-app-download.d.ts +2 -0
- package/dist/esm/components/db-section-app-download.js +1 -1
- package/dist/esm/components/db-section-contact.d.ts +2 -0
- package/dist/esm/components/db-section-contact.js +1 -1
- package/dist/esm/components/db-section-cta.d.ts +3 -0
- package/dist/esm/components/db-section-cta.js +1 -1
- package/dist/esm/components/db-section-faq.d.ts +2 -0
- package/dist/esm/components/db-section-faq.js +1 -1
- package/dist/esm/components/db-section-feature.d.ts +3 -0
- package/dist/esm/components/db-section-feature.js +1 -1
- package/dist/esm/components/db-section-hero.d.ts +2 -0
- package/dist/esm/components/db-section-hero.js +1 -1
- package/dist/esm/components/db-section-logo-cloud.d.ts +2 -0
- package/dist/esm/components/db-section-logo-cloud.js +1 -1
- package/dist/esm/components/db-section-pricing.d.ts +3 -0
- package/dist/esm/components/db-section-pricing.js +1 -1
- package/dist/esm/components/db-section-stats.d.ts +2 -0
- package/dist/esm/components/db-section-stats.js +1 -1
- package/dist/esm/components/db-section-testimonials.d.ts +4 -0
- package/dist/esm/components/db-section-testimonials.js +1 -1
- package/dist/esm/components/db-section.d.ts +2 -0
- package/dist/esm/components/db-section.js +1 -1
- package/dist/esm/components/db-share.d.ts +5 -0
- package/dist/esm/components/db-share.js +1 -1
- package/dist/esm/components/db-sidebar.d.ts +7 -0
- package/dist/esm/components/db-sidebar.js +1 -1
- package/dist/esm/components/db-stat.d.ts +2 -0
- package/dist/esm/components/db-stat.js +1 -1
- package/dist/esm/components/db-table.d.ts +5 -0
- package/dist/esm/components/db-table.js +1 -1
- package/dist/esm/components/db-testimonial.d.ts +3 -0
- package/dist/esm/components/db-testimonial.js +1 -1
- package/dist/esm/components/db-time-picker.d.ts +1 -0
- package/dist/esm/components/db-time-picker.js +1 -1
- package/dist/esm/components/db-top-banner.d.ts +3 -0
- package/dist/esm/components/db-top-banner.js +1 -1
- package/dist/esm/components/db-tutorial.d.ts +3 -0
- package/dist/esm/components/db-tutorial.js +1 -1
- package/dist/esm/components/db-video-timeline.d.ts +34 -2
- package/dist/esm/components/db-video-timeline.js +1 -1
- package/dist/esm/components/db-world-map.d.ts +5 -0
- package/dist/esm/components/media-editor-model.d.ts +10 -1
- package/dist/esm/core/i18n-en.js +1 -1
- package/dist/esm/core/i18n.d.ts +11 -0
- package/dist/esm/core/i18n.js +1 -1
- package/dist/esm/index.d.ts +2 -1
- package/dist/esm/index.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.ts +619 -486
- package/dist/index.esm.js +1 -1
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.d.ts +47 -3
- package/dist/react/index.esm.js +1 -1
- package/docs/ACCORDION.md +17 -0
- package/docs/ACHIEVEMENTS.md +15 -0
- package/docs/AI-ELEMENTS.md +86 -0
- package/docs/APP-UPDATE.md +60 -0
- package/docs/ATTACHMENTS.md +32 -0
- package/docs/BUTTON.md +17 -0
- package/docs/CDN-GUIDE.md +82 -0
- package/docs/COMPONENT-CHECKLIST.md +98 -0
- package/docs/CONTEXT-MENU.md +22 -0
- package/docs/CREDIT-AI.md +136 -0
- package/docs/CREDIT-CARD.md +52 -0
- package/docs/CROSS_PLATFORM_COMPONENT_STRATEGY.md +81 -0
- package/docs/EASING-EDITOR.md +42 -0
- package/docs/EFFECT-KEYFRAMES.md +60 -0
- package/docs/LAYER-LIST.md +31 -0
- package/docs/MEDIA-EDITORS.md +63 -0
- package/docs/MODULE-REUSE.md +43 -0
- package/docs/MULTI-PLATFORM-GUIDE.md +246 -0
- package/docs/NOTIFICATIONS.md +23 -0
- package/docs/PAPER-CARDS.md +61 -0
- package/docs/QUALITY-GUIDELINES.md +196 -0
- package/docs/RANGE-SLIDER.md +29 -0
- package/docs/REACT-WC-INTEGRATION.md +96 -0
- package/docs/RECENT-COMPONENTS-QUALITY.md +96 -0
- package/docs/SELECT.md +26 -0
- package/docs/SELECTION-CONTROLS.md +33 -0
- package/docs/SITE-SHELL.md +37 -0
- package/docs/STYLING.md +60 -0
- package/docs/SUPPORT.md +39 -0
- package/docs/TABS.md +19 -0
- package/docs/TEXT-FIELDS.md +28 -0
- package/docs/TIME-PICKER-DEVELOPMENT.md +115 -0
- package/docs/TOGGLE.md +40 -0
- package/docs/TRAVEL.md +30 -0
- package/docs/UI-NATIVE.md +90 -0
- package/docs/VIDEO-EXPORT.md +12 -0
- package/docs/VOICE-INPUT.md +24 -0
- package/docs/VUE-ANGULAR-INTEGRATION.md +197 -0
- package/docs/WORDPRESS-INTEGRATION.md +250 -0
- package/docs/WORKSPACE.md +27 -0
- package/docs/quality/AXE-REPORT.md +35 -0
- package/docs/quality/CREDIT-AI-RELEASE-2026-10-18.md +34 -0
- package/docs/quality/ENUM-MIGRATION-WORKSHEET.md +288 -0
- package/docs/quality/SCORECARD.md +389 -0
- package/package.json +136 -130
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
<!-- Generated from docs/VUE-ANGULAR-INTEGRATION.md by scripts/sync-package-docs.mjs. -->
|
|
2
|
+
# Vue 3 / Angular Custom Elements 통합 가이드
|
|
3
|
+
|
|
4
|
+
`@designbasekorea/ui-wc`를 Vue 3와 Angular에서 사용하는 상세 설정입니다. 향후 `@designbasekorea/ui-vue`가 추가되면 Vue 공개 API는 `Button`, `Input`, `Tabs` wrapper 이름을 사용하고, 내부 구현은 같은 `db-*` 원본을 감쌉니다.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Vue 3
|
|
9
|
+
|
|
10
|
+
### 설치
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @designbasekorea/ui-wc @designbasekorea/tokens @designbasekorea/theme
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
### main.ts
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
import { createApp } from 'vue';
|
|
20
|
+
import App from './App.vue';
|
|
21
|
+
|
|
22
|
+
import '@designbasekorea/tokens/dist/css/tokens.css';
|
|
23
|
+
import '@designbasekorea/theme/dist/css/theme.css';
|
|
24
|
+
import '@designbasekorea/ui-wc/dist/index.css';
|
|
25
|
+
import '@designbasekorea/ui-wc';
|
|
26
|
+
|
|
27
|
+
createApp(App).mount('#app');
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Custom Element 인식 (선택)
|
|
31
|
+
|
|
32
|
+
Vue 3는 `db-*` 태그를 기본적으로 unknown element로 처리하지만 정상 동작합니다.
|
|
33
|
+
빌드 경고를 줄이려면 `vite.config.ts`:
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import { defineConfig } from 'vite';
|
|
37
|
+
import vue from '@vitejs/plugin-vue';
|
|
38
|
+
|
|
39
|
+
export default defineConfig({
|
|
40
|
+
plugins: [
|
|
41
|
+
vue({
|
|
42
|
+
template: {
|
|
43
|
+
compilerOptions: {
|
|
44
|
+
isCustomElement: (tag) => tag.startsWith('db-'),
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
}),
|
|
48
|
+
],
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### 컴포넌트 사용
|
|
53
|
+
|
|
54
|
+
```vue
|
|
55
|
+
<script setup lang="ts">
|
|
56
|
+
function onSave() {
|
|
57
|
+
console.log('saved');
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function onInput(e: Event) {
|
|
61
|
+
console.log((e as CustomEvent).detail);
|
|
62
|
+
}
|
|
63
|
+
</script>
|
|
64
|
+
|
|
65
|
+
<template>
|
|
66
|
+
<db-button variant="primary" @db-click="onSave">저장</db-button>
|
|
67
|
+
<db-input label="이름" placeholder="입력하세요" @db-input="onInput" />
|
|
68
|
+
<db-tabs labels="홈,설정" :active-index="0">
|
|
69
|
+
<div slot="panel-0">홈</div>
|
|
70
|
+
<div slot="panel-1">설정</div>
|
|
71
|
+
</db-tabs>
|
|
72
|
+
</template>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### v-model 패턴 (Input)
|
|
76
|
+
|
|
77
|
+
WC는 네이티브 `v-model`을 지원하지 않습니다. thin wrapper 예:
|
|
78
|
+
|
|
79
|
+
```vue
|
|
80
|
+
<!-- DbInput.vue -->
|
|
81
|
+
<script setup lang="ts">
|
|
82
|
+
const model = defineModel<string>({ default: '' });
|
|
83
|
+
|
|
84
|
+
function handleInput(e: Event) {
|
|
85
|
+
model.value = (e as CustomEvent<{ value: string }>).detail.value;
|
|
86
|
+
}
|
|
87
|
+
</script>
|
|
88
|
+
|
|
89
|
+
<template>
|
|
90
|
+
<db-input
|
|
91
|
+
:value="model"
|
|
92
|
+
@db-input="handleInput"
|
|
93
|
+
/>
|
|
94
|
+
</template>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### TypeScript
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
// env.d.ts
|
|
101
|
+
declare module 'vue' {
|
|
102
|
+
export interface GlobalComponents {
|
|
103
|
+
'db-button': typeof HTMLElement;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Angular
|
|
111
|
+
|
|
112
|
+
### 설치
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
npm install @designbasekorea/ui-wc @designbasekorea/tokens @designbasekorea/theme
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### angular.json
|
|
119
|
+
|
|
120
|
+
```json
|
|
121
|
+
"styles": [
|
|
122
|
+
"node_modules/@designbasekorea/tokens/dist/css/tokens.css",
|
|
123
|
+
"node_modules/@designbasekorea/theme/dist/css/theme.css",
|
|
124
|
+
"node_modules/@designbasekorea/ui-wc/dist/index.css"
|
|
125
|
+
]
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### main.ts
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
import '@designbasekorea/ui-wc';
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### 컴포넌트
|
|
135
|
+
|
|
136
|
+
```ts
|
|
137
|
+
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
|
138
|
+
|
|
139
|
+
@Component({
|
|
140
|
+
selector: 'app-root',
|
|
141
|
+
standalone: true,
|
|
142
|
+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
143
|
+
template: `
|
|
144
|
+
<db-button variant="primary" (db-click)="onSave()">저장</db-button>
|
|
145
|
+
<db-badge variant="success">완료</db-badge>
|
|
146
|
+
`,
|
|
147
|
+
})
|
|
148
|
+
export class AppComponent {
|
|
149
|
+
onSave() {
|
|
150
|
+
console.log('saved');
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
> Angular는 `(db-click)`으로 CustomEvent를 바인딩합니다.
|
|
156
|
+
|
|
157
|
+
### NgModule 사용 시
|
|
158
|
+
|
|
159
|
+
```ts
|
|
160
|
+
@NgModule({
|
|
161
|
+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
162
|
+
// ...
|
|
163
|
+
})
|
|
164
|
+
export class AppModule {}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## 이벤트 목록
|
|
170
|
+
|
|
171
|
+
| 이벤트 | 컴포넌트 | detail |
|
|
172
|
+
|--------|----------|--------|
|
|
173
|
+
| `db-click` | db-button | — |
|
|
174
|
+
| `db-input` | db-input | `{ value: string }` |
|
|
175
|
+
| `db-change` | db-checkbox, db-toggle, db-tabs, db-dropdown | 컴포넌트별 |
|
|
176
|
+
| `db-close` | db-modal | — |
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Thin wrapper 검토 요약
|
|
181
|
+
|
|
182
|
+
| 프레임워크 | wrapper 필요성 | 이유 |
|
|
183
|
+
|------------|----------------|------|
|
|
184
|
+
| Vue 3 | Input 등 **선택적** | `v-model` 편의 |
|
|
185
|
+
| Angular | **낮음** | `CUSTOM_ELEMENTS_SCHEMA` + 템플릿 바인딩으로 충분 |
|
|
186
|
+
| React | **권장** | 합성 이벤트·ref 패턴 |
|
|
187
|
+
|
|
188
|
+
공식 thin wrapper 패키지(`@designbasekorea/ui-vue`)는 Phase 3 이후 demand에 따라 추가 검토합니다.
|
|
189
|
+
현재는 WC + 위 패턴으로 충분합니다.
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## 관련 문서
|
|
194
|
+
|
|
195
|
+
- [MULTI-PLATFORM-GUIDE.md](./MULTI-PLATFORM-GUIDE.md)
|
|
196
|
+
- [CROSS_PLATFORM_COMPONENT_STRATEGY.md](./CROSS_PLATFORM_COMPONENT_STRATEGY.md)
|
|
197
|
+
- [REACT-WC-INTEGRATION.md](./REACT-WC-INTEGRATION.md)
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
<!-- Generated from docs/WORDPRESS-INTEGRATION.md by scripts/sync-package-docs.mjs. -->
|
|
2
|
+
# WordPress 관리자에서 @designbasekorea/ui-wc 사용하기
|
|
3
|
+
|
|
4
|
+
WordPress **wp-admin** 플러그인·테마 설정 화면에서 `@designbasekorea/ui-wc` Web Components를 쓰는 방법입니다.
|
|
5
|
+
|
|
6
|
+
> React wrapper(`@designbasekorea/ui-wc/react`)는 관리자 PHP 화면에서는 필요 없습니다. `<db-button>` 같은 Custom Elements + 순수 JS가 가장 단순합니다.
|
|
7
|
+
|
|
8
|
+
## 설치할 패키지
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @designbasekorea/ui-wc @designbasekorea/tokens @designbasekorea/theme
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
| 패키지 | 역할 |
|
|
15
|
+
|--------|------|
|
|
16
|
+
| `@designbasekorea/tokens` | `--db-*` 디자인 토큰 CSS |
|
|
17
|
+
| `@designbasekorea/theme` | 라이트/다크 테마 CSS |
|
|
18
|
+
| `@designbasekorea/ui-wc` | Web Components JS + 컴포넌트 스타일 |
|
|
19
|
+
|
|
20
|
+
## 플러그인 assets 구조
|
|
21
|
+
|
|
22
|
+
빌드 결과물을 플러그인에 복사해 self-host 합니다.
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
wp-content/plugins/my-plugin/
|
|
26
|
+
├── my-plugin.php
|
|
27
|
+
├── includes/admin-page.php
|
|
28
|
+
├── assets/
|
|
29
|
+
│ ├── admin.js
|
|
30
|
+
│ └── designbase/
|
|
31
|
+
│ ├── tokens.css ← tokens/dist/css/tokens.css
|
|
32
|
+
│ ├── theme.css ← theme/dist/css/theme.css
|
|
33
|
+
│ └── ui-wc/
|
|
34
|
+
│ ├── index.css
|
|
35
|
+
│ ├── index.esm.js
|
|
36
|
+
│ └── chunks/ ← lazy chunk (Lottie, Prism 등) — 필수
|
|
37
|
+
└── package.json ← (선택) vendor 복사 스크립트
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
`chunks/` 폴더를 빼면 `db-lottie`, `db-code-block` 사용 시 로드가 실패할 수 있습니다.
|
|
41
|
+
|
|
42
|
+
### vendor 복사 스크립트 (선택)
|
|
43
|
+
|
|
44
|
+
```json
|
|
45
|
+
{
|
|
46
|
+
"scripts": {
|
|
47
|
+
"vendor:copy": "cp node_modules/@designbasekorea/tokens/dist/css/tokens.css assets/designbase/ && cp node_modules/@designbasekorea/theme/dist/css/theme.css assets/designbase/ && cp -R node_modules/@designbasekorea/ui-wc/dist assets/designbase/ui-wc"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## PHP: 관리자에서만 enqueue
|
|
55
|
+
|
|
56
|
+
본인 플러그인 메뉴에서만 로드하세요. wp-admin 전역에 올리면 무겁고 스타일 충돌이 납니다.
|
|
57
|
+
|
|
58
|
+
```php
|
|
59
|
+
<?php
|
|
60
|
+
function my_plugin_admin_assets( string $hook ): void {
|
|
61
|
+
if ( $hook !== 'toplevel_page_my-plugin-settings' ) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
$base = plugins_url( 'assets/designbase/', __FILE__ );
|
|
66
|
+
$ver = '0.1.0'; // npm 배포 버전과 맞출 것
|
|
67
|
+
|
|
68
|
+
wp_enqueue_style( 'db-tokens', $base . 'tokens.css', [], $ver );
|
|
69
|
+
wp_enqueue_style( 'db-theme', $base . 'theme.css', [ 'db-tokens' ], $ver );
|
|
70
|
+
wp_enqueue_style( 'db-ui-wc', $base . 'ui-wc/index.css', [ 'db-theme' ], $ver );
|
|
71
|
+
|
|
72
|
+
// WordPress 6.5+
|
|
73
|
+
wp_enqueue_script_module(
|
|
74
|
+
'db-ui-wc',
|
|
75
|
+
$base . 'ui-wc/index.esm.js',
|
|
76
|
+
[],
|
|
77
|
+
$ver
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
wp_enqueue_script_module(
|
|
81
|
+
'my-plugin-admin',
|
|
82
|
+
plugins_url( 'assets/admin.js', __FILE__ ),
|
|
83
|
+
[ 'db-ui-wc' ],
|
|
84
|
+
$ver
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
wp_localize_script( 'my-plugin-admin', 'MyPluginAdmin', [
|
|
88
|
+
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
|
|
89
|
+
'nonce' => wp_create_nonce( 'my_plugin_save' ),
|
|
90
|
+
] );
|
|
91
|
+
}
|
|
92
|
+
add_action( 'admin_enqueue_scripts', 'my_plugin_admin_assets' );
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### WordPress 6.5 미만
|
|
96
|
+
|
|
97
|
+
`wp_enqueue_script_module`이 없으면 플러그인 `admin.js`를 Vite/Webpack으로 `ui-wc`까지 번들링하거나, 설정 페이지 footer에 `type="module"` 스크립트를 인라인합니다.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## PHP: 설정 화면 마크업
|
|
102
|
+
|
|
103
|
+
```php
|
|
104
|
+
<div class="wrap my-plugin-wrap" data-theme="light">
|
|
105
|
+
<h1><?php esc_html_e( '내 플러그인 설정', 'my-plugin' ); ?></h1>
|
|
106
|
+
|
|
107
|
+
<db-card variant="default" size="m">
|
|
108
|
+
<div class="designbase-wc-card__body">
|
|
109
|
+
<db-input
|
|
110
|
+
id="site-title"
|
|
111
|
+
label="사이트 제목"
|
|
112
|
+
value="<?php echo esc_attr( get_option( 'my_plugin_site_title', '' ) ); ?>"
|
|
113
|
+
placeholder="제목 입력"
|
|
114
|
+
></db-input>
|
|
115
|
+
|
|
116
|
+
<db-toggle id="enable-feature">기능 활성화</db-toggle>
|
|
117
|
+
|
|
118
|
+
<div style="margin-top: 16px; display: flex; gap: 8px;">
|
|
119
|
+
<db-button id="save-btn" variant="primary">저장</db-button>
|
|
120
|
+
<db-button id="reset-btn" variant="secondary">초기화</db-button>
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
</db-card>
|
|
124
|
+
|
|
125
|
+
<db-alert
|
|
126
|
+
id="save-alert"
|
|
127
|
+
hidden
|
|
128
|
+
variant="success"
|
|
129
|
+
title="저장 완료"
|
|
130
|
+
message="설정이 저장되었습니다."
|
|
131
|
+
></db-alert>
|
|
132
|
+
</div>
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
`data-theme="light"` 또는 `dark`를 wrapper에 두면 theme CSS가 적용됩니다.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## JS: 이벤트 & AJAX (`assets/admin.js`)
|
|
140
|
+
|
|
141
|
+
일반 DOM `click`이 아니라 **`db-*` 커스텀 이벤트**를 사용합니다.
|
|
142
|
+
|
|
143
|
+
```js
|
|
144
|
+
const saveBtn = document.getElementById('save-btn');
|
|
145
|
+
const titleInput = document.getElementById('site-title');
|
|
146
|
+
const featureToggle = document.getElementById('enable-feature');
|
|
147
|
+
const alertEl = document.getElementById('save-alert');
|
|
148
|
+
|
|
149
|
+
saveBtn?.addEventListener('db-click', async () => {
|
|
150
|
+
const body = new FormData();
|
|
151
|
+
body.append('action', 'my_plugin_save_settings');
|
|
152
|
+
body.append('nonce', MyPluginAdmin.nonce);
|
|
153
|
+
body.append('site_title', titleInput?.getAttribute('value') || '');
|
|
154
|
+
body.append(
|
|
155
|
+
'enable_feature',
|
|
156
|
+
featureToggle?.hasAttribute('checked') ? '1' : '0'
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
const res = await fetch(MyPluginAdmin.ajaxUrl, {
|
|
160
|
+
method: 'POST',
|
|
161
|
+
body,
|
|
162
|
+
credentials: 'same-origin',
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
if (res.ok && alertEl) {
|
|
166
|
+
alertEl.hidden = false;
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
titleInput?.addEventListener('db-input', (e) => {
|
|
171
|
+
titleInput.setAttribute('helper-text', `현재 값: ${e.detail.value || '-'}`);
|
|
172
|
+
});
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### AJAX 핸들러 (PHP)
|
|
176
|
+
|
|
177
|
+
```php
|
|
178
|
+
add_action( 'wp_ajax_my_plugin_save_settings', function () {
|
|
179
|
+
check_ajax_referer( 'my_plugin_save', 'nonce' );
|
|
180
|
+
|
|
181
|
+
update_option( 'my_plugin_site_title', sanitize_text_field( $_POST['site_title'] ?? '' ) );
|
|
182
|
+
update_option( 'my_plugin_enable_feature', ( $_POST['enable_feature'] ?? '' ) === '1' );
|
|
183
|
+
|
|
184
|
+
wp_send_json_success();
|
|
185
|
+
} );
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## 이벤트 · 속성 치트시트
|
|
191
|
+
|
|
192
|
+
| 컴포넌트 | 이벤트 | 값 |
|
|
193
|
+
|----------|--------|-----|
|
|
194
|
+
| `db-button` | `db-click` | — |
|
|
195
|
+
| `db-input` | `db-input` | `event.detail.value` |
|
|
196
|
+
| `db-textarea` | `db-input` | `event.detail.value` |
|
|
197
|
+
| `db-toggle`, `db-checkbox` | `db-change` | `event.detail.checked` |
|
|
198
|
+
| `db-select` | `db-change` | `event.detail.value` |
|
|
199
|
+
| `db-tabs` | `db-change` | `event.detail` (인덱스 등) |
|
|
200
|
+
| `db-modal` | `db-close` | — |
|
|
201
|
+
|
|
202
|
+
값 읽기/쓰기는 대부분 **HTML attribute**입니다.
|
|
203
|
+
|
|
204
|
+
```js
|
|
205
|
+
el.getAttribute('value');
|
|
206
|
+
el.setAttribute('value', '새 값');
|
|
207
|
+
el.setAttribute('checked', '');
|
|
208
|
+
el.removeAttribute('checked');
|
|
209
|
+
modal.setAttribute('open', '');
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
JSON 속성(`options`, `items`, `columns` 등)은 PHP에서 `wp_json_encode()`로 출력하세요.
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## CDN으로 빠른 테스트
|
|
217
|
+
|
|
218
|
+
로컬 플러그인 전에 관리자 화면에서만 시험할 때:
|
|
219
|
+
|
|
220
|
+
```php
|
|
221
|
+
wp_enqueue_style( 'db-tokens', 'https://unpkg.com/@designbasekorea/tokens@0.2.5/dist/css/tokens.css' );
|
|
222
|
+
wp_enqueue_style( 'db-theme', 'https://unpkg.com/@designbasekorea/theme@0.2.8/dist/css/theme.css' );
|
|
223
|
+
wp_enqueue_style( 'db-ui-wc', 'https://unpkg.com/@designbasekorea/ui-wc@0.7.3/dist/index.css' );
|
|
224
|
+
wp_enqueue_script_module(
|
|
225
|
+
'db-ui-wc',
|
|
226
|
+
'https://unpkg.com/@designbasekorea/ui-wc@0.7.3/dist/index.esm.js'
|
|
227
|
+
);
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
운영 플러그인은 **assets 복사(self-host)** 를 권장합니다.
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## wp-admin 주의사항
|
|
235
|
+
|
|
236
|
+
1. **페이지 범위** — `admin_enqueue_scripts`의 `$hook`으로 본인 메뉴만 로드
|
|
237
|
+
2. **스타일 충돌** — `.wrap` 안에 배치; 필요 시 `--db-*` 토큰만 덮어쓰기
|
|
238
|
+
3. **다크 모드** — wrapper `data-theme`을 관리자 색상·`prefers-color-scheme`에 맞게 전환
|
|
239
|
+
4. **보안** — AJAX는 `check_ajax_referer` + `sanitize_*` / `wp_kses_*` 적용
|
|
240
|
+
5. **번들 크기** — ESM 메인 ~650KB; Lottie/CodeBlock 미사용 시 lazy chunk는 로드되지 않음
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## 관련 문서
|
|
245
|
+
|
|
246
|
+
- [멀티플랫폼 가이드](./MULTI-PLATFORM-GUIDE.md)
|
|
247
|
+
- [Vue / Angular 통합](./VUE-ANGULAR-INTEGRATION.md)
|
|
248
|
+
- [CDN 가이드](./CDN-GUIDE.md)
|
|
249
|
+
- [ui-wc 패키지 README](../README.md)
|
|
250
|
+
- [Vanilla 시작 예제](./CDN-GUIDE.md)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# 워크스페이스 표시·초대 모듈 (개발 소스)
|
|
2
|
+
|
|
3
|
+
WorkspaceMembers / WorkspaceInviteModal은 실제 Avatar·Badge·Input·Select·Modal·Button을 조합한다. 메일/초대 토큰/수락/권한/DB를 구현하지 않으며 새 runtime dependency나 인증 공급자는 없다. 기존 exports 삭제/버전 발행·starter r2 snapshot 교체도 없다.
|
|
4
|
+
|
|
5
|
+
## WorkspaceMembers
|
|
6
|
+
|
|
7
|
+
HTML은 `.members`, React는 `members` 배열로 {id,name,email,roleLabel,state,canReinvite?}를 전달한다. state는 active/invited/expired다. 잘못된/중복 id를 제외하며 이름·이메일·역할은 텍스트다. 역할과 상태는 서버의 결과이며 클라이언트에서 추정하지 않는다. inviteLabel을 제공할 때만 초대 버튼이 나온다. pending/loading/disabled는 액션을 막는다. error는 기존 목록과 재시도를 표시한다.
|
|
8
|
+
|
|
9
|
+
onDbInvite는 초대 모달을 여는 의도, onDbReinvite는 {detail:{id}}, onDbRetry는 목록 새로 읽기 의도다. active 항목은 다시 초대 액션이 없고, invited/expired 중 canReinvite가 명시된 항목만 표시한다. 서버는 UI 상태와 별개로 소유권·허용 역할·재발송 제한·기간을 검증해야 한다.
|
|
10
|
+
|
|
11
|
+
## WorkspaceInviteModal
|
|
12
|
+
|
|
13
|
+
roles: {id,label}[]와 선택 defaultRoleId/open/title/description/loading/disabled/error/resetKey를 제공한다. roles는 앱의 허용 목록이며 내장 소유자/관리자/무료 플랜 정책은 없다. 모달은 이메일과 선택 역할의 로컬 미저장 draft를 소유한다. draft getter는 복사본이다.
|
|
14
|
+
|
|
15
|
+
onDbInvite는 {detail:{email,roleId}}다. 이메일은 공백 제거 후 1~254자와 실제 HTML email validity를 검사하고, roleId는 현재 제공 목록에 있어야 한다. placeholder는 name@company.com이다. blur/제출 오류·수정 후 해제·Enter 제출을 지원한다. 서버의 형식/도메인/중복/초대 정책을 대체하지 않는다.
|
|
16
|
+
|
|
17
|
+
취소나 서버 오류에서는 draft를 보존한다. 서버 확인 후 앱이 open=false로 닫고 resetKey를 변경하면 다음 초대에서 초기화된다. loading 중에는 제출/닫기를 막는다. onDbDraftChange로 앱의 이전 서버 오류를 정리하고 onDbClose로 취소를 받는다. 제품은 중복 요청 키와 멤버십 트랜잭션을 서버에서 따로 검증한다.
|
|
18
|
+
|
|
19
|
+
기존 Modal이 포커스 트랩·포털·스크롤 잠금을 소유한다. 목록이 재렌더링돼 초대 트리거가 교체되는 경우에는 소비 앱이 닫힌 뒤 새 트리거로 포커스를 복원해야 한다. 예제 WorkspaceExample에서 이를 보여준다.
|
|
20
|
+
|
|
21
|
+
## 소비 예제와 검증
|
|
22
|
+
|
|
23
|
+
credit-wallet.html#workspace-example은 example.com 계정·중복 입력·실패·초대 대기·만료 재초대를 메모리에서 시험한다. 실제 초대 메일을 보내지 않고 invited를 active로 바꾸지 않는다. 실패와 중복에서는 입력과 선택을 보존한다. 초대 수락·멤버 제거·역할 수정은 후속 범위다.
|
|
24
|
+
|
|
25
|
+
`node scripts/test-workspace-ui.mjs`는 DB_UI_EXAMPLE_URL로 고정된 example 번들을 검증한다. development server 기본값5180과 production runtime 검사를 구분한다. 새 모듈은 source UI/예제에만 연결했고 설치 snapshot 전달·실제 제품 적용은 별도다.
|
|
26
|
+
|
|
27
|
+
세부 간격 변수·모바일·포커스 보완은 [최근 모듈 품질 계약](./RECENT-COMPONENTS-QUALITY.md)을 따른다.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# ui-wc 런타임 접근성 리포트
|
|
2
|
+
|
|
3
|
+
> ⚠️ **자동 생성 파일 — 직접 수정하지 마세요.**
|
|
4
|
+
> `npm run audit:axe` 로 재생성됩니다. 규칙 정의는 [QUALITY-GUIDELINES.md](../QUALITY-GUIDELINES.md).
|
|
5
|
+
|
|
6
|
+
생성일: 2026-11-06 · 픽스처 16개 · axe critical/serious **0건** · 키보드 시나리오 실패 **0건** · 토큰 레이어(색 대비) **0건**
|
|
7
|
+
|
|
8
|
+
axe-core 는 라이트/다크 두 테마에서 각각 실행합니다. 키보드 시나리오는 axe 가 검증할 수 없는
|
|
9
|
+
포커스 트랩·포커스 복원·roving tabindex·폼 참여를 실제 조작으로 확인합니다.
|
|
10
|
+
|
|
11
|
+
## 요약
|
|
12
|
+
|
|
13
|
+
| 픽스처 | axe (라이트) | axe (다크) | 키보드 시나리오 | 콘솔 오류 |
|
|
14
|
+
|---|---|---|---|---|
|
|
15
|
+
| `db-ai-elements` | ✓ | ✓ | — | ✓ |
|
|
16
|
+
| `db-button` | ✓ | ✓ | — | ✓ |
|
|
17
|
+
| `db-checkbox` | ✓ | ✓ | ✓ 통과 | ✓ |
|
|
18
|
+
| `db-credit-ai` | ✓ | ✓ | — | ✓ |
|
|
19
|
+
| `db-credit-ai-react` | ✓ | ✓ | — | ✓ |
|
|
20
|
+
| `db-drawer` | ✓ | ✓ | ✓ 통과 | ✓ |
|
|
21
|
+
| `db-input` | ✓ | ✓ | ✓ 통과 | ✓ |
|
|
22
|
+
| `db-magicui-components` | ✓ | ✓ | — | ✓ |
|
|
23
|
+
| `db-modal` | ✓ | ✓ | ✓ 통과 | ✓ |
|
|
24
|
+
| `db-navigation-rail` | ✓ | ✓ | — | ✓ |
|
|
25
|
+
| `db-recent-quality` | ✓ | ✓ | — | ✓ |
|
|
26
|
+
| `db-section` | ✓ | ✓ | ✓ 통과 | ✓ |
|
|
27
|
+
| `db-select` | ✓ | ✓ | — | ✓ |
|
|
28
|
+
| `db-sidebar-accordion` | ✓ | ✓ | — | ✓ |
|
|
29
|
+
| `db-tabs` | ✓ | ✓ | ✓ 통과 | ✓ |
|
|
30
|
+
| `db-toast` | ✓ | ✓ | ✓ 통과 | ✓ |
|
|
31
|
+
|
|
32
|
+
## 상세
|
|
33
|
+
|
|
34
|
+
위반 없음.
|
|
35
|
+
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<!-- Generated from docs/evidence/CREDIT_AI_UI_2026-10-18.md by scripts/sync-package-docs.mjs. -->
|
|
2
|
+
# 크레딧·AI 공통 UI 실행 기록 — 2026-10-18
|
|
3
|
+
|
|
4
|
+
변경 대상은 Designbase Library의 `packages/ui-wc`이며 기존 스타터킷 소비 tarball/lockfile은 교체하지 않았다. 새 export는 로컬 빌드 산출물에서 사용할 수 있다. 기존 ui-wc 0.8.13 기반의 호환 추가이며 다음 minor 대상으로 CHANGELOG와 ADR-CREDIT-AI-UI에 기록했다. 신규 런타임 의존성은 없다.
|
|
5
|
+
|
|
6
|
+
## 구현
|
|
7
|
+
|
|
8
|
+
- `src/components/db-credit-balance.{ts,scss,css,stories.ts}`: 가용 잔액/예약/누적 사용, 부족·로딩·오류·compact·충전 이벤트.
|
|
9
|
+
- `db-credit-recharge.*`: 상품 런타임 검증, native radio controlled 선택, 키보드/포커스, 결제 진입 이벤트, 로딩/오류·빈 상태.
|
|
10
|
+
- `db-ai-task-status.*`: idle/queued/running/succeeded/failed/cancelled/needs_attention, 서버 진행률 또는 스피너, 예약·차감·취소/재시도/확인 이벤트.
|
|
11
|
+
- define/index/react/styles 등록, i18n, 기존 버튼·진행바·스피너 조합, Storybook 및 design-examples 갤러리/검색/사용 API 등록.
|
|
12
|
+
- 상세 소비 계약: `packages/ui-wc/docs/CREDIT-AI.md`.
|
|
13
|
+
|
|
14
|
+
## 실행
|
|
15
|
+
|
|
16
|
+
| 실제 명령 | 결과와 범위 |
|
|
17
|
+
| --- | --- |
|
|
18
|
+
| `npm run typecheck --prefix packages/ui-wc` | 통과. 실제 전체 UI 라이브러리 TypeScript 검사. |
|
|
19
|
+
| `npm run build --prefix packages/ui-wc` | 통과. 기본/React ESM+CJS, d.ts, 개별 ESM, CSS. 최초 SCSS @use 위치 오류를 수정한 후 재실행 통과. |
|
|
20
|
+
| `npm run build:check --prefix examples/design-examples` | 통과. 갤러리 전체 TypeScript + Vite production build. 기존 대형 번들 경고는 유지. |
|
|
21
|
+
| `node scripts/verify-wc-examples.mjs` | 통과. 126개 활성 예제의 데모 연결. |
|
|
22
|
+
| `npm run verify:docs --prefix packages/ui-wc` | 통과. 갤러리/속성/가이드 정합성 검사. |
|
|
23
|
+
| `node scripts/audit-wc-quality.mjs --only db-credit-balance,db-credit-recharge,db-ai-task-status` | 스크립트가 전체 133개를 감사했고 P0 위반 0개. 정적 검사이며 접근성 실사용 판정은 아니다. |
|
|
24
|
+
| `node scripts/test-credit-ai.mjs` | **56개 통과**. 결과는 `credit-ai-2026-10-18/checks.json`과 browser.log. Chromium 실제 DOM·클릭/키보드/선택/이벤트/재연결/유효하지 않은 입력/테마/너비/React wrapper를 검사. |
|
|
25
|
+
|
|
26
|
+
브라우저 실행은 최초 sandbox의 localhost listen EPERM 이후 localhost 권한으로 실행했다. 검증 코드의 db-button 네이티브 button 가정, 숨긴 spinner와 중복 status 선택자, React 시험 번들의 NODE_ENV 설정과 React 비동기 상태 반영 대기를 수정했다. 컴포넌트에 가짜 성공을 추가해 검사를 우회하지 않았다.
|
|
27
|
+
|
|
28
|
+
밝은/어두운 테마 1100px·390px 캡처를 저장하고 화면을 확인했다. 넘침과 신규 스타일에서 사용하는 토큰의 실제 해석을 검사한다. 표시 문자열은 HTML로 해석되지 않으며 진행률 없는 작업은 %를 만들지 않는다. 확인 대기에서는 재시도 버튼이 없다.
|
|
29
|
+
|
|
30
|
+
## 검증 경계
|
|
31
|
+
|
|
32
|
+
실제 결제·크레딧 충전/지급·외부 AI 호출·실제 Supabase·운영 DB·원격 배포·공개 npm publish는 실행하지 않았다. 선택/작업/결제 이벤트는 의도 전달이며 서버 최종 인가/정산을 대신하지 않는다. 스타터 앱의 기존 설치본은 그대로여서 신규 UI 자동 적용 완료로 계산하지 않는다.
|
|
33
|
+
|
|
34
|
+
스타터킷에서는 `pnpm verify` 24단계를 통과했다. `pnpm release:check`는 live-supabase/live-notices의 현재 소스 증거 및 P1-009/P2-006 때문에 차단된다. UI 단독 완료와 전체 제품 운영 수용을 구분한다. 스타터 기록은 `docs/evidence/UI_CREDIT_LIBRARY_2026-10-18.md`다.
|