@designbasekorea/wordpress-ui 0.1.5 → 0.1.6

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.
@@ -2,7 +2,8 @@
2
2
 
3
3
  이 문서는 `@designbasekorea/wordpress-ui`를 WordPress 플러그인과 테마의 관리자 화면에 적용하는 표준 가이드입니다.
4
4
 
5
- 이 가이드의 기준 배포 버전은 `0.1.5`입니다. 플러그인 또는 테마의 lockfile과
5
+ 이 가이드의 기준 배포 버전은 `0.1.6`입니다. `@designbasekorea/ui-wc@0.8.7`과
6
+ 같은 세트를 사용하세요. 플러그인 또는 테마의 lockfile과
6
7
  vendor 산출물도 같은 버전으로 맞추고, 버전을 올릴 때마다 아래 검증 명령을 다시
7
8
  실행합니다.
8
9
 
@@ -39,7 +40,7 @@ WordPress plugin/theme
39
40
 
40
41
  ### 1.1 WordPress 전역 관리자와 플러그인 내부 shell의 경계
41
42
 
42
- `AdminShell`과 `AdminSidebar`는 플러그인 또는 테마 내부 화면을 위한 것입니다. 다음 전역 요소는 수정하지 않습니다.
43
+ `db-admin-shell`과 React `AdminShell`은 플러그인 또는 테마 **내부 화면**을 위한 것입니다. 다음 전역 요소는 수정하지 않습니다.
43
44
 
44
45
  - `#adminmenu`
45
46
  - `#wpadminbar`
@@ -62,7 +63,7 @@ WordPress plugin/theme
62
63
  ### 2.1 Node 프로젝트에 설치
63
64
 
64
65
  ```bash
65
- npm install @designbasekorea/wordpress-ui@0.1.5
66
+ npm install @designbasekorea/wordpress-ui@0.1.6
66
67
  ```
67
68
 
68
69
  WordPress 서버가 npm을 실행하는 것이 아닙니다. 라이브러리를 설치한 뒤 플러그인 또는 테마 빌드 과정에서 배포에 필요한 파일을 포함해야 합니다.
@@ -143,7 +144,7 @@ require_once __DIR__ . '/vendor/wordpress-ui/wordpress-ui.php';
143
144
 
144
145
  final class MyPlugin_Admin_Assets
145
146
  {
146
- private const UI_VERSION = '0.1.5';
147
+ private const UI_VERSION = '0.1.6';
147
148
 
148
149
  public static function init(): void
149
150
  {
@@ -267,15 +268,16 @@ WordPress 플러그인과 테마의 기본 선택지는 vanilla/PHP입니다. Re
267
268
  ### 4.1 페이지 기본 구조
268
269
 
269
270
  PHP 템플릿은 `.designbase-wp-admin` root 안에서 `db-admin-shell`을 선언하는 방식을
270
- 권장합니다. 이 Web Component가 실제 `db-sidebar`, 플러그인명 브랜드,
271
+ 권장합니다. 이 Web Component가 실제 `db-sidebar`, 플러그인명 로고,
271
272
  `db-page-header`, 콘텐츠용 `<db-container size="full" padding="l" full-width>`를
272
- 하나의 패턴으로 렌더링합니다. 기존 템플릿을 단계적으로 이전하는 동안에는 화면별
273
- adapter가 같은 `db-admin-shell`을 생성하도록 사용할 수 있습니다.
273
+ 하나의 패턴으로 렌더링합니다.
274
274
 
275
- `sections`/`items`는 PHP에서 `wp_json_encode()`로 전달하고, 링크·권한·활성 상태는
276
- 소비 플러그인이나 테마가 관리합니다. 일반적인 화면은 아래처럼 `db-admin-shell` 하나를
277
- 선언하면 됩니다. 직접 자식 `db-page-header`는 헤더로 유지되고, 나머지 자식은 shell이
278
- `db-container` 안으로 이동합니다.
275
+ `title`(또는 `brand`) 사이드바 **헤더 로고**입니다. 메뉴는 `items` JSON으로 넘기고,
276
+ 링크·권한·활성 상태는 소비 플러그인이나 테마가 계산합니다. 메뉴를 실제 그룹으로 나눌
277
+ 때만 `sections`를 쓰고, 그룹 제목에 플러그인명을 넣지 않습니다.
278
+
279
+ 직접 자식 `db-page-header`는 헤더로 유지되고, 나머지 자식은 shell이 `db-container`
280
+ 안으로 이동합니다.
279
281
 
280
282
  ```php
281
283
  <?php
@@ -284,7 +286,7 @@ $sidebar_items = [
284
286
  'id' => 'dashboard',
285
287
  'label' => __('대시보드', 'myplugin'),
286
288
  'href' => admin_url('admin.php?page=myplugin'),
287
- 'icon' => 'doughnut-chart',
289
+ 'icon' => 'dashboard',
288
290
  'active' => (($_GET['page'] ?? '') === 'myplugin'),
289
291
  ],
290
292
  [
@@ -299,21 +301,15 @@ $sidebar_items = [
299
301
  <div class="wrap designbase-wp-admin myplugin-admin">
300
302
  <db-admin-shell
301
303
  title="My Plugin"
302
- sections='<?php echo esc_attr(wp_json_encode([[
303
- 'id' => 'main',
304
- 'title' => 'My Plugin',
305
- 'items' => $sidebar_items,
306
- ]])); ?>'>
304
+ items="<?php echo esc_attr(wp_json_encode($sidebar_items)); ?>"
305
+ >
307
306
  <db-page-header
308
307
  title="<?php esc_attr_e('대시보드', 'myplugin'); ?>"
309
308
  description="<?php esc_attr_e('플러그인 상태와 최근 작업을 확인합니다.', 'myplugin'); ?>"
310
- variant="minimal"
311
- align="left">
312
- <div slot="actions">
313
- <a class="button button-secondary" href="<?php echo esc_url(admin_url('admin.php?page=myplugin-settings')); ?>">
314
- <?php esc_html_e('설정', 'myplugin'); ?>
315
- </a>
316
- </div>
309
+ variant="minimal">
310
+ <a slot="actions" class="button button-secondary" href="<?php echo esc_url(admin_url('admin.php?page=myplugin-settings')); ?>">
311
+ <?php esc_html_e('설정', 'myplugin'); ?>
312
+ </a>
317
313
  </db-page-header>
318
314
 
319
315
  <db-section title="<?php esc_attr_e('콘텐츠', 'myplugin'); ?>">
@@ -409,10 +405,10 @@ select?.addEventListener('db-change', (event) => {
409
405
  아이콘은 이모지나 임의의 유니코드 문자를 사용하지 않고 Designbase icons 이름을 사용합니다.
410
406
 
411
407
  ```html
412
- <i class="dbwp-admin-icon icon-dashboard" aria-hidden="true"></i>
413
- <i class="dbwp-admin-icon icon-file-manager" aria-hidden="true"></i>
414
- <i class="dbwp-admin-icon icon-search" aria-hidden="true"></i>
415
- <i class="dbwp-admin-icon icon-settings" aria-hidden="true"></i>
408
+ <i class="icon-dashboard" aria-hidden="true"></i>
409
+ <i class="icon-file-manager" aria-hidden="true"></i>
410
+ <i class="icon-search" aria-hidden="true"></i>
411
+ <i class="icon-settings" aria-hidden="true"></i>
416
412
  ```
417
413
 
418
414
  `styles.css`가 아이콘 폰트와 `@font-face` 규칙을 포함합니다. 아이콘이 보이지 않으면 다음을 확인합니다.
@@ -427,20 +423,21 @@ select?.addEventListener('db-change', (event) => {
427
423
  React는 선택 사항입니다. Gutenberg나 기존 React 앱과 연결해야 하는 화면에서만 사용하고, 일반적인 PHP admin page에는 vanilla entry를 권장합니다.
428
424
 
429
425
  ```bash
430
- npm install @designbasekorea/wordpress-ui@0.1.5 react react-dom
426
+ npm install @designbasekorea/wordpress-ui@0.1.6 react react-dom
431
427
  ```
432
428
 
433
429
  ```tsx
434
430
  import '@designbasekorea/wordpress-ui/styles.css';
435
431
  import {
436
- AdminDataTable,
437
- AdminEmptyState,
438
- AdminFilterBar,
439
432
  AdminPage,
440
433
  AdminPageContent,
441
434
  AdminPageHeader,
442
- AdminSection,
443
435
  AdminShell,
436
+ Button,
437
+ SearchBar,
438
+ Section,
439
+ Select,
440
+ Table,
444
441
  type AdminNavItem,
445
442
  } from '@designbasekorea/wordpress-ui/react';
446
443
 
@@ -451,59 +448,61 @@ const sidebarItems: AdminNavItem[] = [
451
448
 
452
449
  export function MyPluginAdmin() {
453
450
  return (
454
- <div className="designbase-wp-admin">
455
- <AdminShell sidebarItems={sidebarItems} sidebarTitle="My Plugin">
456
- <AdminPage>
457
- <AdminPageHeader
458
- title="콘텐츠 관리"
459
- icon="file-manager"
460
- description="콘텐츠를 검색하고 상태를 관리합니다."
461
- />
462
- <AdminPageContent maxWidth="xl">
463
- <AdminSection title="검색 및 필터">
464
- <AdminFilterBar
465
- searchPlaceholder="제목 검색"
466
- statusPlaceholder="전체 상태"
467
- statusOptions={[
468
- { value: 'all', label: '전체 상태' },
469
- { value: 'published', label: '공개' },
470
- { value: 'draft', label: '임시글' },
471
- ]}
472
- onSubmit={(event) => {
473
- event.preventDefault();
474
- // REST 또는 URL query 변경은 소비 앱이 담당한다.
475
- }}
476
- />
477
- </AdminSection>
478
- <AdminSection title="목록">
479
- <AdminDataTable
480
- columns={[
481
- { id: 'title', header: '제목', key: 'title', sortable: true },
482
- { id: 'status', header: '상태', key: 'status' },
483
- ]}
484
- rows={[]}
485
- emptyState={<AdminEmptyState title="콘텐츠가 없습니다." />}
486
- />
487
- </AdminSection>
488
- </AdminPageContent>
489
- </AdminPage>
490
- </AdminShell>
491
- </div>
451
+ <AdminShell sidebarItems={sidebarItems} sidebarTitle="My Plugin">
452
+ <AdminPageHeader
453
+ title="콘텐츠 관리"
454
+ description="콘텐츠를 검색하고 상태를 관리합니다."
455
+ actions={<Button variant="primary" size="s">새 페이지</Button>}
456
+ />
457
+ <AdminPage>
458
+ <AdminPageContent>
459
+ <Section title="검색 및 필터">
460
+ <form
461
+ className="designbase-wp-admin__filter-bar"
462
+ role="search"
463
+ onSubmit={(event) => {
464
+ event.preventDefault();
465
+ // REST 또는 URL query 변경은 소비 앱이 담당한다.
466
+ }}
467
+ >
468
+ <div className="designbase-wp-admin__filter-bar-toolbar">
469
+ <SearchBar name="search" placeholder="제목 검색" aria-label="제목 검색" />
470
+ <Select
471
+ name="status"
472
+ aria-label="상태"
473
+ options={JSON.stringify([
474
+ { value: 'all', label: '전체 상태' },
475
+ { value: 'published', label: '공개' },
476
+ { value: 'draft', label: '임시글' },
477
+ ])}
478
+ />
479
+ </div>
480
+ </form>
481
+ </Section>
482
+ <Section title="목록" fullWidth>
483
+ <Table
484
+ columns={JSON.stringify([
485
+ { key: 'title', header: '제목', sortable: true },
486
+ { key: 'status', header: '상태' },
487
+ ])}
488
+ data={JSON.stringify([])}
489
+ rowKey="id"
490
+ emptyMessage="콘텐츠가 없습니다."
491
+ />
492
+ </Section>
493
+ </AdminPageContent>
494
+ </AdminPage>
495
+ </AdminShell>
492
496
  );
493
497
  }
494
498
  ```
495
499
 
496
- React adapter의 책임은 관리자 shell과 컴포넌트 조합입니다.
500
+ React adapter의 책임은 관리자 shell과 ui-wc primitives 조합입니다.
497
501
 
498
- - `AdminShell`: 내부 sidebar와 main layout
499
- - `AdminSidebar`: 메뉴, active 상태, badge, 모바일 close
502
+ - `AdminShell`: `sidebarTitle`(사이드바 로고)과 `sidebarItems`(메뉴). 내부에서 `.designbase-wp-admin` root를 만듭니다.
500
503
  - `AdminPage`, `AdminPageContent`: 페이지 폭과 밀도
501
- - `AdminPageHeader`: title, icon, description, breadcrumb, action, back link
502
- - `AdminSection`: 제목, 설명, action, optional collapse
503
- - `AdminFilterBar`: 검색과 상태 필터 표현
504
- - `AdminTabs`: 탭 표현과 active 상태
505
- - `AdminDataTable`: column, row, sort, loading, empty, error 상태 표현
506
- - `AdminEmptyState`, `AdminLoadingState`, `AdminErrorState`: 상태 화면
504
+ - `AdminPageHeader`: title, description, breadcrumb, action. 모바일에서는 메뉴 버튼을 붙입니다.
505
+ - `Section`, `Table`, `SearchBar`, `Select`, `Tabs`, `EmptyState`, `Modal` 등: 같은 패키지의 React primitives. `AdminSection` / `AdminDataTable` / `AdminFilterBar` 같은 별도 래퍼는 없습니다.
507
506
 
508
507
  이 컴포넌트들은 REST 요청, 페이지네이션 API, nonce 갱신, capability 검사를 대신하지 않습니다. React state와 서버 데이터의 생명주기는 플러그인/테마 앱이 소유합니다.
509
508
 
@@ -638,14 +637,14 @@ register_setting('myplugin', 'myplugin_options', [
638
637
  ```text
639
638
  .designbase-wp-admin
640
639
  └─ AdminShell 또는 db-admin-shell
641
- ├─ AdminSidebar 또는 plugin 내부 nav
640
+ ├─ db-sidebar (title/sidebarTitle = 플러그인명 로고, items = 메뉴)
642
641
  └─ main
643
642
  ├─ AdminPageHeader / db-page-header
644
- ├─ AdminTabs / db-tabs (필요한 경우)
643
+ ├─ Tabs / db-tabs (필요한 경우)
645
644
  └─ AdminPageContent
646
- ├─ AdminSection / db-section
647
- ├─ AdminFilterBar
648
- └─ AdminDataTable 또는 native table
645
+ ├─ Section / db-section
646
+ ├─ form.designbase-wp-admin__filter-bar
647
+ └─ Table / db-table 또는 native table
649
648
  ```
650
649
 
651
650
  ### 7.1 페이지 헤더
@@ -660,7 +659,7 @@ register_setting('myplugin', 'myplugin_options', [
660
659
 
661
660
  ### 7.2 section
662
661
 
663
- 서로 다른 목적의 콘텐츠를 하나의 큰 카드에 몰아넣지 않습니다. 제목·설명·action이 있는 `AdminSection` 또는 `db-section`으로 묶습니다. 접기 상태를 제공할 때에는 키보드로 열고 닫을 수 있어야 하며, 기본 상태는 콘텐츠 중요도에 따라 결정합니다.
662
+ 서로 다른 목적의 콘텐츠를 하나의 큰 카드에 몰아넣지 않습니다. 제목·설명·action이 있는 `Section` 또는 `db-section`으로 묶습니다. 접기 상태를 제공할 때에는 키보드로 열고 닫을 수 있어야 하며, 기본 상태는 콘텐츠 중요도에 따라 결정합니다.
664
663
 
665
664
  ### 7.3 filter bar
666
665
 
@@ -674,13 +673,13 @@ register_setting('myplugin', 'myplugin_options', [
674
673
 
675
674
  ### 7.4 data table
676
675
 
677
- 단순한 표는 native `<table>`을 우선 사용합니다. 정렬·행 action·empty/loading/error가 반복되거나 React 데이터 모델을 사용하는 경우 `AdminDataTable` 또는 `db-table`을 사용합니다.
676
+ 단순한 표는 native `<table>`을 우선 사용합니다. 정렬·행 action·empty/loading/error가 반복되거나 React 데이터 모델을 사용하는 경우 `Table` 또는 `db-table`을 사용합니다.
678
677
 
679
678
  - 열 제목을 `<th>`로 출력합니다.
680
679
  - 행 action은 명확한 accessible name을 사용합니다.
681
680
  - 정렬 방향은 텍스트나 `aria-sort`로 전달합니다.
682
681
  - 로딩 중 기존 데이터가 있으면 전체 레이아웃을 깜빡이지 않고 해당 영역만 busy로 표시합니다.
683
- - 데이터가 없을 때 빈 `<table>`만 보여주지 말고 `AdminEmptyState`를 제공합니다.
682
+ - 데이터가 없을 때 빈 `<table>`만 보여주지 말고 `empty-message` 또는 `EmptyState` / `db-empty-state`를 제공합니다.
684
683
  - 삭제·상태 변경 action은 서버 응답이 성공한 뒤 목록을 갱신합니다.
685
684
 
686
685
  ## 8. 상태 표현과 오류 처리
@@ -689,9 +688,9 @@ register_setting('myplugin', 'myplugin_options', [
689
688
 
690
689
  | 상태 | 사용자에게 보여줄 것 | 권장 구현 |
691
690
  | --- | --- | --- |
692
- | loading | 작업 중임과 예상 영역 | `AdminLoadingState`, `db-spinner`, `db-skeleton` |
693
- | empty | 결과가 없다는 설명과 다음 action | `AdminEmptyState`, `db-empty-state` |
694
- | error | 문제와 재시도 방법 | `AdminErrorState`, `db-alert` |
691
+ | loading | 작업 중임과 예상 영역 | `Spinner` / `db-spinner`, `Skeleton` / `db-skeleton` |
692
+ | empty | 결과가 없다는 설명과 다음 action | `EmptyState` / `db-empty-state`, `db-table`의 `empty-message` |
693
+ | error | 문제와 재시도 방법 | `Alert` / `db-alert` |
695
694
  | success | 저장·삭제 완료 피드백 | toast + 변경된 영역 갱신 |
696
695
  | unauthorized | 권한 부족 안내 | 서버의 403/WordPress 권한 화면과 일치 |
697
696
 
@@ -794,9 +793,9 @@ body { ... }
794
793
  2. 화면 root에 `.designbase-wp-admin`을 추가합니다.
795
794
  3. 해당 화면에만 `styles.css`와 `browser.iife.js`를 enqueue합니다.
796
795
  4. 기존 페이지 header/content 영역을 `AdminPageHeader` 또는 `db-page-header` 구조로 바꿉니다.
797
- 5. 반복되는 section을 `AdminSection` 또는 `db-section`으로 정리합니다.
798
- 6. 검색·필터 화면에 `AdminFilterBar` 또는 native-first filter markup을 적용합니다.
799
- 7. 목록 화면에 `AdminDataTable` 또는 semantic native table을 적용합니다.
796
+ 5. 반복되는 section을 `Section` 또는 `db-section`으로 정리합니다.
797
+ 6. 검색·필터 화면에 `form.designbase-wp-admin__filter-bar`와 `SearchBar`/`db-search-bar`를 적용합니다.
798
+ 7. 목록 화면에 `Table`/`db-table` 또는 semantic native table을 적용합니다.
800
799
  8. loading·empty·error·success 상태를 분리합니다.
801
800
  9. modal, confirm, toast, drawer를 필요한 화면에만 추가합니다.
802
801
  10. REST·AJAX·Settings API·capability 동작은 UI migration 중 변경하지 않고 회귀 테스트합니다.
@@ -898,7 +897,7 @@ import '@designbasekorea/wordpress-ui/browser';
898
897
  import '@designbasekorea/wordpress-ui/styles.css';
899
898
 
900
899
  // React 화면에서만 허용
901
- import { AdminShell, AdminDataTable } from '@designbasekorea/wordpress-ui/react';
900
+ import { AdminShell, Table } from '@designbasekorea/wordpress-ui/react';
902
901
  import { DbButton, DbInput, DbSelect, DbModal } from '@designbasekorea/wordpress-ui/components';
903
902
  // 또는: import { DbButton, DbInput, DbSelect, DbModal } from '@designbasekorea/wordpress-ui';
904
903
 
@@ -11,7 +11,7 @@
11
11
  <db-admin-shell
12
12
  id="wordpress-ui-example-shell"
13
13
  title="PageNest"
14
- sections='[{"id":"main","title":"PageNest","items":[{"id":"dashboard","label":"대시보드","href":"#dashboard","icon":"dashboard","active":true},{"id":"pages","label":"페이지 목록","href":"#pages","icon":"file-manager","badge":12},{"id":"settings","label":"설정","href":"#settings","icon":"settings"}]}]'
14
+ items='[{"id":"dashboard","label":"대시보드","href":"#dashboard","icon":"dashboard","active":true},{"id":"pages","label":"페이지 목록","href":"#pages","icon":"file-manager","badge":12},{"id":"settings","label":"설정","href":"#settings","icon":"settings"}]'
15
15
  >
16
16
  <db-page-header
17
17
  title="페이지 목록"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@designbasekorea/wordpress-ui",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "WordPress 관리자용 Designbase UI primitives와 plugin shell patterns",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -74,7 +74,7 @@
74
74
  "build-storybook": "storybook build"
75
75
  },
76
76
  "dependencies": {
77
- "@designbasekorea/ui-wc": "0.8.6"
77
+ "@designbasekorea/ui-wc": "0.8.7"
78
78
  },
79
79
  "peerDependencies": {
80
80
  "react": ">=18.0.0 <20.0.0",