{"_id":"@bluewardai/ui5-controls","_rev":"6-bc0feeb511e52573fbc0daa085dd7a6d","name":"@bluewardai/ui5-controls","dist-tags":{"latest":"2.0.0"},"versions":{"1.1.0":{"name":"@bluewardai/ui5-controls","version":"1.1.0","keywords":["ui5","sapui5","controls","tabbar","approval-comments"],"author":{"name":"rendez0829"},"license":"MIT","_id":"@bluewardai/ui5-controls@1.1.0","maintainers":[{"name":"rendez0829","email":"rendez0829@gmail.com"}],"ui5":{"dependencies":[]},"dist":{"shasum":"99ff46218618a3b5f30254d9b163ba099b2cf25d","tarball":"https://registry.npmjs.org/@bluewardai/ui5-controls/-/ui5-controls-1.1.0.tgz","fileCount":75,"integrity":"sha512-7Kvt7yYJNJBlWRAvr4jOPZN3qpxBLt3r0D97jLcZHqaYnlQYaUPzqS9uAayo3eALYA3Ggjp4OQXU2N0YPEBRfg==","signatures":[{"sig":"MEUCIQC6jIjSRNmeAgrnEutdbiJLc+5Gu/6JT9g/qoEnDir7lQIgfxrzQdSH2mB4a6yPNGmNphwzMuH8dX65P8GzEtcy4Kw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1832283},"gitHead":"9324d1f6a3cf5dd2d65d8510c173b9cc9c59dad9","scripts":{"build":"npm run build:tiptap && npm run build:grid && ui5 build --clean-dest","check":"find src/blueward/ui/controls -name '*.js' ! -path '*/lib/*' -exec node --check {} \\;","build:grid":"esbuild src/blueward/ui/controls/grid/index.js --bundle --minify --legal-comments=inline --format=iife --outfile=src/blueward/ui/controls/lib/grid-table-bundle.min.js","build:tiptap":"esbuild scripts/tiptap-entry.js --bundle --minify --legal-comments=inline --banner:js=\"/*! Tiptap open-source packages - MIT License - Copyright (c) Tiptap GmbH */\" --format=iife --global-name=BluewardTiptap --outfile=src/blueward/ui/controls/lib/tiptap-bundle.min.js"},"_npmUser":{"name":"rendez0829","email":"rendez0829@gmail.com"},"copyright":"Copyright (c) 2026 rendez0829","_npmVersion":"10.9.8","description":"Reusable UI5 controls for Blueward applications","directories":{},"_nodeVersion":"22.23.1","dependencies":{"@tiptap/pm":"^3.30.3","@tiptap/core":"^3.30.3","@tiptap/starter-kit":"^3.30.3","@tiptap/extension-color":"^3.30.3","@tiptap/extension-table":"^3.30.3","@tiptap/extension-highlight":"^3.30.3","@tiptap/extension-text-align":"^3.30.3","@tiptap/extension-text-style":"^3.30.3","@tiptap/extension-placeholder":"^3.30.3"},"_hasShrinkwrap":false,"devDependencies":{"esbuild":"^0.28.2","@ui5/cli":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ui5-controls_1.1.0_1788234424957_0.8756182323754704","host":"s3://npm-registry-packages-npm-production"}},"1.1.1":{"name":"@bluewardai/ui5-controls","version":"1.1.1","keywords":["ui5","sapui5","controls","tabbar","approval-comments"],"author":{"name":"rendez0829"},"license":"MIT","_id":"@bluewardai/ui5-controls@1.1.1","maintainers":[{"name":"rendez0829","email":"rendez0829@gmail.com"}],"ui5":{"dependencies":[]},"dist":{"shasum":"fbf4a21ce6e3ecc2c55d3620f02cc702a104835c","tarball":"https://registry.npmjs.org/@bluewardai/ui5-controls/-/ui5-controls-1.1.1.tgz","fileCount":75,"integrity":"sha512-2atStzWnhJcBu92RlQrbGTpNJwx2RmdyBwVUT/sjsC0jjgy2ITJ/gnoZOgX+k59moQ04U7JBuGNCmP4QWcmU4w==","signatures":[{"sig":"MEYCIQCiOPmObOQEYLPsClhm04Sdr89lYIW6mxAiPpuL/oktlgIhANXDSrHcnn8FzJ/rrQ28xEaFhIM9nXV28fXAen6hFjW0","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1821617},"gitHead":"9324d1f6a3cf5dd2d65d8510c173b9cc9c59dad9","scripts":{"build":"npm run build:tiptap && npm run build:grid && ui5 build --clean-dest","check":"find src/blueward/ui/controls -name '*.js' ! -path '*/lib/*' -exec node --check {} \\;","build:grid":"esbuild src/blueward/ui/controls/grid/index.js --bundle --minify --legal-comments=inline --format=iife --outfile=src/blueward/ui/controls/lib/grid-table-bundle.min.js","build:tiptap":"esbuild scripts/tiptap-entry.js --bundle --minify --legal-comments=inline --banner:js=\"/*! Tiptap open-source packages - MIT License - Copyright (c) Tiptap GmbH */\" --format=iife --global-name=BluewardTiptap --outfile=src/blueward/ui/controls/lib/tiptap-bundle.min.js"},"_npmUser":{"name":"rendez0829","email":"rendez0829@gmail.com"},"copyright":"Copyright (c) 2026 rendez0829","_npmVersion":"10.9.8","description":"Reusable UI5 controls for Blueward applications","directories":{},"_nodeVersion":"22.23.1","dependencies":{"@tiptap/pm":"^3.30.3","@tiptap/core":"^3.30.3","@tiptap/starter-kit":"^3.30.3","@tiptap/extension-color":"^3.30.3","@tiptap/extension-table":"^3.30.3","@tiptap/extension-highlight":"^3.30.3","@tiptap/extension-text-align":"^3.30.3","@tiptap/extension-text-style":"^3.30.3","@tiptap/extension-placeholder":"^3.30.3"},"_hasShrinkwrap":false,"devDependencies":{"esbuild":"^0.28.2","@ui5/cli":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ui5-controls_1.1.1_1788234734661_0.878371234641526","host":"s3://npm-registry-packages-npm-production"}},"1.1.2":{"name":"@bluewardai/ui5-controls","version":"1.1.2","keywords":["ui5","sapui5","controls","tabbar","approval-comments"],"author":{"name":"rendez0829"},"license":"MIT","_id":"@bluewardai/ui5-controls@1.1.2","maintainers":[{"name":"rendez0829","email":"rendez0829@gmail.com"}],"ui5":{"dependencies":[]},"dist":{"shasum":"586d7fad6eb66657f41fe35b58f236ce983073ca","tarball":"https://registry.npmjs.org/@bluewardai/ui5-controls/-/ui5-controls-1.1.2.tgz","fileCount":75,"integrity":"sha512-xPdmmYJ8CT0X6FR7ry6Ip1cvnkhg4saY2+ueBxlaNjeBvn43OOGfx5zGzgFz+i4exzwSVK9sYx1xQdqB56hAlQ==","signatures":[{"sig":"MEUCIQDZ1n/w+vaHhE9PB7v7WT4t6GAw2tM8Xu0u4TcpMBb6YAIgBvYoXFiViU0CQ18ulkp++ZJv2Rr2ivZy/EG2HHk3WyQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1821422},"gitHead":"9324d1f6a3cf5dd2d65d8510c173b9cc9c59dad9","scripts":{"build":"npm run build:tiptap && npm run build:grid && ui5 build --clean-dest","check":"find src/blueward/ui/controls -name '*.js' ! -path '*/lib/*' -exec node --check {} \\;","build:grid":"esbuild src/blueward/ui/controls/grid/index.js --bundle --minify --legal-comments=inline --format=iife --outfile=src/blueward/ui/controls/lib/grid-table-bundle.min.js","build:tiptap":"esbuild scripts/tiptap-entry.js --bundle --minify --legal-comments=inline --banner:js=\"/*! Tiptap open-source packages - MIT License - Copyright (c) Tiptap GmbH */\" --format=iife --global-name=BluewardTiptap --outfile=src/blueward/ui/controls/lib/tiptap-bundle.min.js"},"_npmUser":{"name":"rendez0829","email":"rendez0829@gmail.com"},"copyright":"Copyright (c) 2026 rendez0829","_npmVersion":"10.9.8","description":"Reusable UI5 controls for Blueward applications","directories":{},"_nodeVersion":"22.23.1","dependencies":{"@tiptap/pm":"^3.30.3","@tiptap/core":"^3.30.3","@tiptap/starter-kit":"^3.30.3","@tiptap/extension-color":"^3.30.3","@tiptap/extension-table":"^3.30.3","@tiptap/extension-highlight":"^3.30.3","@tiptap/extension-text-align":"^3.30.3","@tiptap/extension-text-style":"^3.30.3","@tiptap/extension-placeholder":"^3.30.3"},"_hasShrinkwrap":false,"devDependencies":{"esbuild":"^0.28.2","@ui5/cli":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ui5-controls_1.1.2_1788235019670_0.27452033459317104","host":"s3://npm-registry-packages-npm-production"}},"1.1.3":{"name":"@bluewardai/ui5-controls","version":"1.1.3","keywords":["ui5","sapui5","controls","tabbar","approval-comments"],"author":{"name":"rendez0829"},"license":"MIT","_id":"@bluewardai/ui5-controls@1.1.3","maintainers":[{"name":"rendez0829","email":"rendez0829@gmail.com"}],"ui5":{"dependencies":[]},"dist":{"shasum":"4500a6a80966e0b031d7f9d40e099733b93e4866","tarball":"https://registry.npmjs.org/@bluewardai/ui5-controls/-/ui5-controls-1.1.3.tgz","fileCount":75,"integrity":"sha512-UIz3+RcSCwuewbGsvwErOPXG+EIOY1Cw9wYiwwvA6E9GoecoUOSLDELSBNuQy8i6QFCk1/go5HrQeLFylr/C3A==","signatures":[{"sig":"MEUCIQCNHwXZ7MRqVzHhGlJc0YdYB4Zs32faPue1UHFkzsv9bwIgPKu+d54s6e5hcKKDYgKqjzP5krwexVr9LB9EVwXBuKA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1823218},"gitHead":"9324d1f6a3cf5dd2d65d8510c173b9cc9c59dad9","scripts":{"build":"npm run build:tiptap && npm run build:grid && ui5 build --clean-dest","check":"find src/blueward/ui/controls -name '*.js' ! -path '*/lib/*' -exec node --check {} \\;","build:grid":"esbuild src/blueward/ui/controls/grid/index.js --bundle --minify --legal-comments=inline --format=iife --outfile=src/blueward/ui/controls/lib/grid-table-bundle.min.js","build:tiptap":"esbuild scripts/tiptap-entry.js --bundle --minify --legal-comments=inline --banner:js=\"/*! Tiptap open-source packages - MIT License - Copyright (c) Tiptap GmbH */\" --format=iife --global-name=BluewardTiptap --outfile=src/blueward/ui/controls/lib/tiptap-bundle.min.js"},"_npmUser":{"name":"rendez0829","email":"rendez0829@gmail.com"},"copyright":"Copyright (c) 2026 rendez0829","_npmVersion":"10.9.8","description":"Reusable UI5 controls for Blueward applications","directories":{},"_nodeVersion":"22.23.1","dependencies":{"@tiptap/pm":"^3.30.3","@tiptap/core":"^3.30.3","@tiptap/starter-kit":"^3.30.3","@tiptap/extension-color":"^3.30.3","@tiptap/extension-table":"^3.30.3","@tiptap/extension-highlight":"^3.30.3","@tiptap/extension-text-align":"^3.30.3","@tiptap/extension-text-style":"^3.30.3","@tiptap/extension-placeholder":"^3.30.3"},"_hasShrinkwrap":false,"devDependencies":{"esbuild":"^0.28.2","@ui5/cli":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ui5-controls_1.1.3_1788235204233_0.16284310004955915","host":"s3://npm-registry-packages-npm-production"}},"1.1.4":{"name":"@bluewardai/ui5-controls","version":"1.1.4","keywords":["ui5","sapui5","controls","tabbar","approval-comments"],"author":{"name":"rendez0829"},"license":"MIT","_id":"@bluewardai/ui5-controls@1.1.4","maintainers":[{"name":"rendez0829","email":"rendez0829@gmail.com"}],"ui5":{"dependencies":[]},"dist":{"shasum":"3b662dec19903396e0ea3419ea2f7b7fdaef3ad8","tarball":"https://registry.npmjs.org/@bluewardai/ui5-controls/-/ui5-controls-1.1.4.tgz","fileCount":75,"integrity":"sha512-vGH48tvUlkAIdMagqQrEvzOQD1hUbwoalbCDhjYFwuvSboZWSIDsNvBUnxTNYUF5LbOpMCTC4Kl90nX9YBubmA==","signatures":[{"sig":"MEUCIF+Bda97vfTw5imV5GtzUFJ1Wb1BKhLzBIhe59/R6JtfAiEA0w252iBl0Z3KARcq1n8AE7RWsD0V20HW/I+/GXbTT1Q=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1833927},"gitHead":"9324d1f6a3cf5dd2d65d8510c173b9cc9c59dad9","scripts":{"build":"npm run build:tiptap && npm run build:grid && ui5 build --clean-dest","check":"find src/blueward/ui/controls -name '*.js' ! -path '*/lib/*' -exec node --check {} \\;","build:grid":"esbuild src/blueward/ui/controls/grid/index.js --bundle --minify --legal-comments=inline --format=iife --outfile=src/blueward/ui/controls/lib/grid-table-bundle.min.js","build:tiptap":"esbuild scripts/tiptap-entry.js --bundle --minify --legal-comments=inline --banner:js=\"/*! Tiptap open-source packages - MIT License - Copyright (c) Tiptap GmbH */\" --format=iife --global-name=BluewardTiptap --outfile=src/blueward/ui/controls/lib/tiptap-bundle.min.js"},"_npmUser":{"name":"rendez0829","email":"rendez0829@gmail.com"},"copyright":"Copyright (c) 2026 rendez0829","_npmVersion":"10.9.8","description":"Reusable UI5 controls for Blueward applications","directories":{},"_nodeVersion":"22.23.1","dependencies":{"@tiptap/pm":"^3.30.3","@tiptap/core":"^3.30.3","@tiptap/starter-kit":"^3.30.3","@tiptap/extension-color":"^3.30.3","@tiptap/extension-table":"^3.30.3","@tiptap/extension-highlight":"^3.30.3","@tiptap/extension-text-align":"^3.30.3","@tiptap/extension-text-style":"^3.30.3","@tiptap/extension-placeholder":"^3.30.3"},"_hasShrinkwrap":false,"devDependencies":{"esbuild":"^0.28.2","@ui5/cli":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ui5-controls_1.1.4_1788239161522_0.27952373362925176","host":"s3://npm-registry-packages-npm-production"}},"2.0.0":{"_id":"@bluewardai/ui5-controls@2.0.0","ui5":{"dependencies":[]},"dist":{"shasum":"50c16d532862f88a7f4c1a44a65af73aed22d4e4","tarball":"https://registry.npmjs.org/@bluewardai/ui5-controls/-/ui5-controls-2.0.0.tgz","fileCount":80,"integrity":"sha512-eAconivoZB9xowfWIujdTJTCas6Fjo+3YZR2bTXIZQuxILy5/v+pgSJ94sg++YlFI4nBIMyNyOpl1L/QeNdQpw==","signatures":[{"sig":"MEUCIQDNuEgxSQQtRyTqH8/HaF6shffkE9eSG0r98xjAmuRjigIgPVGgUJAb1JWAqs2dZBqWOlHqNd/RWydrXT32EmynmV0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQD0bmXQ6VSqvoOUY6NjLQApg336j6JsO0mgez4l8x+78wIhANM6WPAJBsvn8oqE8L9ZfBkHiBOmflMS2+vU6oQoCsHP"}],"unpackedSize":2056444},"name":"@bluewardai/ui5-controls","author":{"name":"rendez0829"},"gitHead":"ece9bbd4a0bca2673a013058a6625e2b3f1b4acc","license":"MIT","scripts":{"build":"npm run build:tiptap && npm run build:grid && ui5 build --clean-dest","check":"find src/blueward/ui/controls -name '*.js' ! -path '*/lib/*' -exec node --check {} \\;","build:grid":"esbuild src/blueward/ui/controls/grid/index.js --bundle --minify --legal-comments=inline --format=iife --outfile=src/blueward/ui/controls/lib/grid-table-bundle.min.js","build:tiptap":"esbuild scripts/tiptap-entry.js --bundle --minify --legal-comments=inline --banner:js=\"/*! Tiptap open-source packages - MIT License - Copyright (c) Tiptap GmbH */\" --format=iife --global-name=BluewardTiptap --outfile=src/blueward/ui/controls/lib/tiptap-bundle.min.js"},"version":"2.0.0","_npmUser":{"name":"rendez0829","email":"rendez0829@gmail.com"},"keywords":["ui5","sapui5","controls","tabbar","approval-comments"],"copyright":"Copyright (c) 2026 rendez0829","_npmVersion":"10.9.8","description":"Reusable UI5 controls for Blueward applications","directories":{},"maintainers":[{"name":"rendez0829","email":"rendez0829@gmail.com"}],"_nodeVersion":"22.23.1","dependencies":{"@tiptap/pm":"^3.30.3","@tiptap/core":"^3.30.3","@tiptap/starter-kit":"^3.30.3","@tiptap/extension-color":"^3.30.3","@tiptap/extension-table":"^3.30.3","@tiptap/extension-highlight":"^3.30.3","@tiptap/extension-text-align":"^3.30.3","@tiptap/extension-text-style":"^3.30.3","@tiptap/extension-placeholder":"^3.30.3"},"_hasShrinkwrap":false,"devDependencies":{"esbuild":"^0.28.2","@ui5/cli":"^3.0.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ui5-controls_2.0.0_1790663024067_0.8553093077156078"}}},"time":{"created":"2026-09-01T03:47:04.732Z","modified":"2026-09-29T06:23:44.350Z","1.1.0":"2026-09-01T03:47:05.121Z","1.1.1":"2026-09-01T03:52:14.834Z","1.1.2":"2026-09-01T03:56:59.825Z","1.1.3":"2026-09-01T04:00:04.420Z","1.1.4":"2026-09-01T05:06:01.694Z","2.0.0":"2026-09-29T06:23:44.172Z"},"author":{"name":"rendez0829"},"license":"MIT","keywords":["ui5","sapui5","controls","tabbar","approval-comments"],"description":"Reusable UI5 controls for Blueward applications","maintainers":[{"name":"rendez0829","email":"rendez0829@gmail.com"}],"readme":"# Blueward UI5 Controls\n\n`@bluewardai/ui5-controls`는 SAPUI5 애플리케이션에서 공통으로 사용할 수 있는 Blueward UI5 Custom Controls 패키지입니다.\n\n이 문서는 컨트롤별 API 설명보다, 실제 소비 애플리케이션에서 npm package를 설치하고 로컬 approuter / UI5 build / BTP HTML5 Application Repository 환경에서 정상 동작시키기 위한 설정 방법과 이유를 설명합니다.\n\n컨트롤별 속성, 허용값, 이벤트 및 예제는 [Control API 문서](docs/README.md)에서 확인할 수 있습니다.\n\n## 패키지 정보\n\n```json\n{\n  \"name\": \"@bluewardai/ui5-controls\",\n  \"version\": \"1.1.4\",\n  \"ui5\": {\n    \"namespace\": \"blueward/ui/controls\"\n  }\n}\n```\n\nUI5 모듈 경로는 다음 namespace를 사용합니다.\n\n```text\nblueward.ui.controls\nblueward/ui/controls\n```\n\nXML View에서는 보통 `bw` prefix를 사용합니다.\n\n```xml\n<mvc:View\n  controllerName=\"sample.controller.Main\"\n  xmlns:mvc=\"sap.ui.core.mvc\"\n  xmlns=\"sap.m\"\n  xmlns:bw=\"blueward.ui.controls\">\n\n  <bw:Button\n    text=\"Blueward Button\"\n    variant=\"primary\"\n    press=\".onPress\" />\n</mvc:View>\n```\n\n## 1. 설치\n\n소비 애플리케이션의 root에서 설치합니다.\n\n```bash\nnpm install @bluewardai/ui5-controls\n```\n\n소비 애플리케이션의 `package.json`에는 `dependencies`와 `ui5.dependencies`를 함께 설정해야 합니다.\n\n```json\n{\n  \"dependencies\": {\n    \"@bluewardai/ui5-controls\": \"^1.1.4\"\n  },\n  \"ui5\": {\n    \"dependencies\": [\n      \"@bluewardai/ui5-controls\"\n    ]\n  }\n}\n```\n\n### 왜 `ui5.dependencies`가 필요한가?\n\n`dependencies`는 npm이 패키지를 `node_modules`에 설치하기 위한 설정입니다. 하지만 UI5 Tooling은 npm dependency 전체를 자동으로 UI5 library로 인식하지 않습니다.\n\n`ui5.dependencies`에 패키지를 등록해야 UI5 Tooling이 해당 패키지의 `ui5.yaml`을 읽고, `blueward.ui.controls`를 UI5 library project로 등록합니다. 이 설정이 빠지면 빌드나 로컬 서버에서 다음 경로를 찾지 못할 수 있습니다.\n\n```text\nresources/blueward/ui/controls/...\n```\n\n설정 후 아래 명령어로 인식 여부를 확인할 수 있습니다.\n\n```bash\nnpx ui5 tree --flat\n```\n\n정상이라면 출력에 다음 항목이 포함됩니다.\n\n```text\nblueward.ui.controls blueward/ui/controls\n```\n\n## 2. UI5 CLI 버전\n\n이 패키지는 `ui5.yaml`에서 `specVersion: \"3.1\"`을 사용합니다. 따라서 소비 애플리케이션은 UI5 CLI 3.x 이상을 사용해야 합니다.\n\n```bash\nnpm install --save-dev @ui5/cli@^3\n```\n\nUI5 CLI 2.x를 사용하면 빌드 또는 `ui5 tree` 실행 시 아래와 같은 오류가 발생할 수 있습니다.\n\n```text\nUnsupported \"specVersion\"\n```\n\n이 오류는 패키지 문제가 아니라, 소비 애플리케이션의 UI5 Tooling 버전이 패키지의 `ui5.yaml` specVersion을 해석하지 못해서 발생합니다.\n\n## 3. 모듈 import\n\nController나 Component에서 일반 UI5 module처럼 import할 수 있습니다.\n\n```js\nsap.ui.define([\n  \"sap/ui/core/mvc/Controller\",\n  \"blueward/ui/controls/Button\"\n], function (Controller, Button) {\n  \"use strict\";\n\n  return Controller.extend(\"sample.controller.Main\", {\n    onInit: function () {\n      this.byId(\"content\").addItem(new Button({\n        text: \"Blueward Button\",\n        variant: \"primary\"\n      }));\n    }\n  });\n});\n```\n\n## 4. CSS / Style 설정\n\nBlueward controls는 패키지 내부의 theme stylesheet를 사용합니다.\n\n```text\nblueward/ui/controls/themes/base/library.css\n```\n\nXML View에서 `<bw:Button />`처럼 개별 control을 바로 사용하는 경우, control JavaScript는 로드되었지만 stylesheet가 아직 삽입되지 않아 버튼이 기본 HTML button처럼 보일 수 있습니다.\n\n이 문제를 막기 위해 화면 Controller마다 `Style`을 넣는 방식은 권장하지 않습니다. CSS는 화면 로직이 아니라 애플리케이션 초기화 책임에 가깝기 때문입니다.\n\n소비 애플리케이션에서는 `Component.js`처럼 앱 시작 시 한 번만 로드되는 module에 `blueward/ui/controls/library`를 등록하는 방식을 권장합니다.\n\n`blueward/ui/controls/library`는 내부에서 `blueward/ui/controls/Style`을 로드하므로, 소비 앱은 Style module을 직접 알 필요가 없습니다.\n\n```js\nsap.ui.define([\n  \"sap/ui/core/UIComponent\",\n  \"blueward/ui/controls/library\"\n], function (UIComponent) {\n  \"use strict\";\n\n  return UIComponent.extend(\"sample.Component\", {\n    metadata: {\n      manifest: \"json\"\n    }\n  });\n});\n```\n\n`library` module은 UI5 library를 초기화하고, 패키지 CSS가 한 번만 로드되도록 보장합니다.\n\n프로젝트에 별도 bootstrap module이 있다면 `Component.js` 대신 그곳에 한 번만 import해도 됩니다. 중요한 기준은 “화면별 Controller에 반복 추가하지 않고, 앱 시작 지점에서 library를 한 번만 로드한다”는 것입니다.\n\n### `manifest.json`의 `sap.ui5.dependencies.libs`에 넣지 않는 이유\n\nCSS를 강제로 로드하려고 `manifest.json`에 아래처럼 추가하는 방식은 권장하지 않습니다.\n\n```json\n{\n  \"sap.ui5\": {\n    \"dependencies\": {\n      \"libs\": {\n        \"blueward.ui.controls\": {}\n      }\n    }\n  }\n}\n```\n\n이 방식은 일부 local approuter / proxy 환경에서 UI5가 custom library preload를 CDN, ABAP app index, 또는 잘못된 runtime 위치에서 찾게 만들 수 있습니다.\n\nBlueward npm package는 SAPUI5 CDN이나 ABAP app index에 존재하는 표준 library가 아니므로, library 초기화는 `blueward/ui/controls/library` import로 처리하고, 파일 제공은 아래의 resource root / approuter / build 설정으로 처리하는 것이 안전합니다.\n\n## 5. Resource root 설정\n\nHTML bootstrap에서 `blueward.ui.controls` namespace가 앱 내부의 `resources/blueward/ui/controls`를 바라보도록 설정합니다.\n\n애플리케이션 root의 `index.html` 기준:\n\n```html\n<script\n  id=\"sap-ui-bootstrap\"\n  data-sap-ui-resourceroots='{\n    \"sample\": \"./\",\n    \"blueward.ui.controls\": \"./resources/blueward/ui/controls\"\n  }'>\n</script>\n```\n\n`test/flpSandbox.html`처럼 한 단계 하위 경로에서 실행되는 파일은 상대 경로가 달라지므로 다음처럼 설정합니다.\n\n```html\n<script\n  id=\"sap-ui-bootstrap\"\n  data-sap-ui-resourceroots='{\n    \"sample\": \"../\",\n    \"blueward.ui.controls\": \"../resources/blueward/ui/controls\"\n  }'>\n</script>\n```\n\n### 왜 app root 상대 경로를 사용하는가?\n\napprouter에서 애플리케이션이 `/myapp/index.html`로 서비스되는 경우, 브라우저의 실제 요청은 보통 아래처럼 나갑니다.\n\n```text\n/myapp/resources/blueward/ui/controls/Button.js\n```\n\n따라서 bootstrap에서는 현재 HTML5 앱 root 기준의 상대 경로를 사용하는 편이 로컬 approuter와 BTP HTML5 Repository 양쪽에서 가장 예측 가능합니다.\n\n## 6. 로컬 approuter 설정\n\n로컬에서 `@sap/approuter`를 사용하고 `xs-app-local.json`이 애플리케이션 `webapp`만 `localDir`로 바라보는 경우, `node_modules`에 설치된 Blueward package 파일은 자동으로 서비스되지 않습니다.\n\n예를 들어 아래 catch-all route만 있으면:\n\n```json\n{\n  \"source\": \"^/myapp/(.*)$\",\n  \"target\": \"$1\",\n  \"localDir\": \"../app/webapp\"\n}\n```\n\n다음 요청은 `webapp/resources/...`에서 파일을 찾게 됩니다.\n\n```text\n/myapp/resources/blueward/ui/controls/Button.js\n```\n\n하지만 로컬 개발 시 Blueward package의 원본 파일은 보통 아래에 있습니다.\n\n```text\n../app/node_modules/@bluewardai/ui5-controls/src/blueward/ui/controls\n```\n\n따라서 `xs-app-local.json`에서 generic app route보다 먼저 Blueward 전용 route를 추가합니다.\n\n```json\n{\n  \"source\": \"^/myapp/resources/blueward/ui/controls/(.*)$\",\n  \"target\": \"$1\",\n  \"localDir\": \"../app/node_modules/@bluewardai/ui5-controls/src/blueward/ui/controls\",\n  \"cacheControl\": \"no-cache, no-store, must-revalidate\"\n},\n{\n  \"source\": \"^/myapp/(.*)$\",\n  \"target\": \"$1\",\n  \"localDir\": \"../app/webapp\",\n  \"cacheControl\": \"no-cache, no-store, must-revalidate\"\n}\n```\n\n중요한 점은 Blueward route가 반드시 catch-all route보다 앞에 있어야 한다는 것입니다. 뒤에 있으면 먼저 catch-all route가 요청을 잡아버려 404가 발생할 수 있습니다.\n\nroute를 수정한 뒤에는 approuter process를 완전히 종료하고 다시 실행해야 합니다. 실행 중인 approuter는 기존 route table을 메모리에 가지고 있으므로 파일만 수정해도 바로 반영되지 않습니다.\n\n## 7. UI5 build 설정\n\n배포용 빌드에서는 `node_modules`의 package source를 runtime에서 직접 읽지 않습니다. 빌드 결과물인 `dist` 또는 배포 ZIP 안에 Blueward resource가 포함되어 있어야 합니다.\n\n소비 애플리케이션의 `ui5.yaml`에 dependency include를 추가합니다.\n\n```yaml\nbuilder:\n  settings:\n    includeDependency:\n      - blueward.ui.controls\n```\n\n빌드 후 아래 파일이 존재해야 합니다.\n\n```text\ndist/resources/blueward/ui/controls/library.js\ndist/resources/blueward/ui/controls/Button.js\ndist/resources/blueward/ui/controls/themes/base/library.css\n```\n\n## 8. `ui5 build preload` / CF build 설정\n\n일부 프로젝트는 CF 배포용으로 별도 `ui5-deploy.yaml`과 `ui5 build preload`를 사용합니다. 이때 config 파일 구조에 따라 `builder.settings`를 넣으면 UI5 Tooling이 허용하지 않는 경우가 있습니다.\n\n그 경우 package dependency를 CLI option으로 명시합니다.\n\n```json\n{\n  \"scripts\": {\n    \"build:cf\": \"ui5 build preload --clean-dest --config ui5-deploy.yaml --include-task=generateCachebusterInfo --include-dependency blueward.ui.controls\"\n  }\n}\n```\n\nBlueward package를 여러 개 사용한다면 `--include-dependency`를 package별로 반복합니다.\n\n```json\n{\n  \"scripts\": {\n    \"build:cf\": \"ui5 build preload --clean-dest --config ui5-deploy.yaml --include-task=generateCachebusterInfo --include-dependency blueward.ui.controls --include-dependency blueward.ui.loading\"\n  }\n}\n```\n\n## 9. `ui5-task-zipper` 사용 시\n\n`ui5-task-zipper`로 `<app-name>.zip`을 생성하는 프로젝트는 `includeDependencies: true`를 설정해야 합니다.\n\n```yaml\nbuilder:\n  customTasks:\n    - name: ui5-task-zipper\n      afterTask: generateCachebusterInfo\n      configuration:\n        archiveName: myapp\n        includeDependencies: true\n        additionalFiles:\n          - xs-app.json\n```\n\n이 설정이 없으면 `dist/resources/blueward/...`에는 파일이 존재하더라도, 최종 ZIP 안에는 dependency resource가 빠질 수 있습니다. 그러면 HTML5 repo mock 또는 BTP HTML5 Application Repository runtime에서 아래 요청이 404가 됩니다.\n\n```text\n/myapp/resources/blueward/ui/controls/Button.js\n```\n\n## 10. BTP HTML5 Application Repository 배포 확인\n\nBTP HTML5 Application Repository에 배포할 때는 최종 artifact 안에 다음 경로가 포함되어야 합니다.\n\n```text\nresources/blueward/ui/controls/\n```\n\n배포 후 브라우저 Network 탭에서 다음 파일들이 200으로 내려오는지 확인합니다.\n\n```text\n/myapp/resources/blueward/ui/controls/library.js\n/myapp/resources/blueward/ui/controls/Button.js\n/myapp/resources/blueward/ui/controls/themes/base/library.css\n```\n\n## 11. reuse library resolver / app index 사용 프로젝트 주의\n\n일부 UI5 프로젝트는 `manifest.json`의 `sap.ui5.dependencies.libs`를 읽어서 `/sap/bc/ui2/app_index/ui5_app_info` 같은 ABAP app index API로 reuse library 위치를 찾는 custom script를 사용합니다.\n\nBlueward npm package는 ABAP app index에 등록된 reuse library가 아니므로, 이런 resolver가 있다면 `blueward.*` namespace는 조회 대상에서 제외해야 합니다.\n\n권장 방식은 다음과 같습니다.\n\n- npm package는 `package.json`의 `dependencies`와 `ui5.dependencies`로 관리\n- runtime 경로는 `resourceroots`와 approuter route로 관리\n- build artifact 포함은 `includeDependency` 또는 `--include-dependency`로 관리\n- CSS는 `blueward/ui/controls/library` 1회 import로 관리\n\n## 12. 문제 해결\n\n### 버튼이 기본 HTML button처럼 보이는 경우\n\nControl JavaScript는 로드되었지만 CSS가 로드되지 않은 상태입니다.\n\n확인할 것:\n\n- `blueward/ui/controls/library`를 앱 초기 module에서 한 번 import했는지\n- Network 탭에서 아래 CSS가 200으로 내려오는지\n\n```text\n/myapp/resources/blueward/ui/controls/themes/base/library.css\n```\n\n### `Button.js`, `library.js`, `library-preload.js`가 404인 경우\n\nNetwork 탭에서 실제 Request URL을 먼저 확인합니다.\n\n- `/myapp/resources/blueward/...`가 404라면 local approuter route 또는 배포 artifact 누락 문제일 가능성이 큽니다.\n- `https://ui5.sap.com/resources/blueward/...`로 요청된다면 custom library를 SAPUI5 CDN에서 찾고 있는 것입니다. `resourceroots` 또는 proxy 설정을 확인해야 합니다.\n- `dist/resources/blueward/...`에는 있는데 ZIP에는 없다면 `ui5-task-zipper`의 `includeDependencies: true`를 확인합니다.\n\n### `net::ERR_BLOCKED_BY_ORB`가 발생하는 경우\n\n브라우저가 JavaScript를 기대했는데 실제 응답이 HTML 404 페이지 또는 잘못된 MIME type인 경우 발생할 수 있습니다.\n\n대부분 원인은 다음 중 하나입니다.\n\n- approuter catch-all route가 Blueward 요청을 먼저 잡음\n- Blueward resource route가 없음\n- resource root가 잘못됨\n- 배포 ZIP에 dependency resource가 빠짐\n- SAPUI5 CDN으로 custom library를 요청함\n\n### 설정을 바꿨는데 계속 404인 경우\n\n로컬 approuter process가 이전 route table을 계속 들고 있을 수 있습니다. `npm run start`로 실행 중인 approuter를 완전히 종료한 뒤 다시 시작합니다.\n\n## License\n\nMIT. See [LICENSE](./LICENSE) and [NOTICE](./NOTICE).\n","readmeFilename":"README.md"}