exsdk-ui5 0.1.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/README.md +67 -0
- package/dist/exsdk.ui5.cjs.js +167 -0
- package/dist/exsdk.ui5.css +1 -0
- package/dist/exsdk.ui5.esm.js +161 -0
- package/dist/exsdk.ui5.umd.js +173 -0
- package/package.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# @exsdk/ui5
|
|
2
|
+
|
|
3
|
+
Modern UI Component SDK for SAP Fiori & UI5.
|
|
4
|
+
|
|
5
|
+
Beautiful, fast, framework-independent components that work inside any Fiori project — no BTP, no migration needed.
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
### CDN (UI5 projeleri için — en kolay yol)
|
|
10
|
+
```html
|
|
11
|
+
<!-- index.html veya flpSandbox.html içine ekle -->
|
|
12
|
+
<script src="https://cdn.exsdk.io/0.1.0/exsdk.ui5.umd.js"></script>
|
|
13
|
+
<link href="https://cdn.exsdk.io/0.1.0/exsdk.ui5.css" rel="stylesheet">
|
|
14
|
+
|
|
15
|
+
<script>
|
|
16
|
+
ExSDK.ExCore.init({ licenseKey: "YOUR_KEY" });
|
|
17
|
+
</script>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### npm
|
|
21
|
+
```bash
|
|
22
|
+
npm install @exsdk/ui5
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
```js
|
|
26
|
+
import ExCore, { ExButton, ExTable } from "@exsdk/ui5";
|
|
27
|
+
import "@exsdk/ui5/css";
|
|
28
|
+
|
|
29
|
+
await ExCore.init({ licenseKey: "YOUR_KEY" });
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## UI5 Custom Control olarak kullanım
|
|
33
|
+
|
|
34
|
+
```xml
|
|
35
|
+
<!-- View XML -->
|
|
36
|
+
<mvc:View
|
|
37
|
+
xmlns:ex="project1.control">
|
|
38
|
+
<ex:ExTable id="myTable" title="Ürünler" columns="{/columns}" rows="{/rows}" />
|
|
39
|
+
<ex:ExButton text="Kaydet" type="primary" press=".onSave" />
|
|
40
|
+
</mvc:View>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Components
|
|
44
|
+
|
|
45
|
+
| Component | Tier | Açıklama |
|
|
46
|
+
|----------------|------------|---------------------------------|
|
|
47
|
+
| ExButton | Free | 8 tip, ripple, loading states |
|
|
48
|
+
| ExTable | Free | Virtual scroll, sort, resize |
|
|
49
|
+
| ExForm | Free | 6 field tipi, validation |
|
|
50
|
+
| ExFileUploader | Free | Drag & drop, preview |
|
|
51
|
+
| ExKanban | Pro | Sürükle-bırak lanes |
|
|
52
|
+
| ExChart | Pro | Line, bar, pie, donut |
|
|
53
|
+
| ExTimeline | Pro | Gantt, bağımlılık |
|
|
54
|
+
| ExDashboard | Enterprise | Widget grid |
|
|
55
|
+
|
|
56
|
+
## Theming
|
|
57
|
+
|
|
58
|
+
```js
|
|
59
|
+
ExCore.theme.apply({
|
|
60
|
+
"--ex-primary": "#FF5A00", // marka rengin
|
|
61
|
+
"--ex-radius": "4px" // köşe yuvarlaklığı
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Docs
|
|
66
|
+
|
|
67
|
+
→ [exsdk.io/docs](https://exsdk.io/docs)
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* @exsdk/ui5 v0.1.0
|
|
3
|
+
* Modern UI Component SDK for SAP Fiori & UI5
|
|
4
|
+
* (c) 2026 ExSDK
|
|
5
|
+
* Released under commercial license — see LICENSE.md
|
|
6
|
+
*/
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const LICENSE_SERVER = "https://license.exsdk.io/v1/verify";
|
|
10
|
+
const LOCAL_KEY = "exsdk_license";
|
|
11
|
+
const CACHE_TTL_MS = 24 * 60 * 60 * 1000;
|
|
12
|
+
|
|
13
|
+
let _tier = "free", _verified = false;
|
|
14
|
+
|
|
15
|
+
const ExLicense = {
|
|
16
|
+
async init(licenseKey) {
|
|
17
|
+
if (!licenseKey) { _tier = "free"; return _tier; }
|
|
18
|
+
const cached = this._getCache(licenseKey);
|
|
19
|
+
if (cached) { _tier = cached.tier; _verified = true; return _tier; }
|
|
20
|
+
try {
|
|
21
|
+
const res = await fetch(LICENSE_SERVER, {
|
|
22
|
+
method: "POST",
|
|
23
|
+
headers: { "Content-Type": "application/json" },
|
|
24
|
+
body: JSON.stringify({ key: licenseKey, domain: window.location.hostname, sdk: "0.1.0" })
|
|
25
|
+
});
|
|
26
|
+
if (!res.ok) throw new Error();
|
|
27
|
+
const data = await res.json();
|
|
28
|
+
_tier = data.tier || "free"; _verified = true;
|
|
29
|
+
this._setCache(licenseKey, _tier);
|
|
30
|
+
} catch {
|
|
31
|
+
console.warn("[ExSDK] License check failed, running in free mode");
|
|
32
|
+
_tier = "free";
|
|
33
|
+
}
|
|
34
|
+
return _tier;
|
|
35
|
+
},
|
|
36
|
+
isRestricted(componentTier) {
|
|
37
|
+
const o = { free: 0, pro: 1, enterprise: 2 };
|
|
38
|
+
return (o[_tier] || 0) < (o[componentTier] || 0);
|
|
39
|
+
},
|
|
40
|
+
getTier() { return _tier; },
|
|
41
|
+
isVerified() { return _verified; },
|
|
42
|
+
isPro() { return _tier === "pro" || _tier === "enterprise"; },
|
|
43
|
+
_getCache(key) {
|
|
44
|
+
try {
|
|
45
|
+
const d = JSON.parse(localStorage.getItem(LOCAL_KEY));
|
|
46
|
+
if (!d || d.key !== key || Date.now() - d.ts > CACHE_TTL_MS) return null;
|
|
47
|
+
return d;
|
|
48
|
+
} catch { return null; }
|
|
49
|
+
},
|
|
50
|
+
_setCache(key, tier) {
|
|
51
|
+
try { localStorage.setItem(LOCAL_KEY, JSON.stringify({ key, tier, ts: Date.now() })); } catch {}
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* ExTheme — CSS token yönetimi
|
|
57
|
+
* Müşteri kendi marka renklerini buradan override eder
|
|
58
|
+
*/
|
|
59
|
+
const DEFAULTS = {
|
|
60
|
+
"--ex-primary": "#0070f2",
|
|
61
|
+
"--ex-primary-hover": "#005fd4",
|
|
62
|
+
"--ex-danger": "#e54646",
|
|
63
|
+
"--ex-success": "#0f8c3b",
|
|
64
|
+
"--ex-warning": "#e8a000",
|
|
65
|
+
"--ex-text": "#1d2d3e",
|
|
66
|
+
"--ex-text-muted": "#556b82",
|
|
67
|
+
"--ex-border": "#e4e5e7",
|
|
68
|
+
"--ex-radius": "8px",
|
|
69
|
+
"--ex-radius-lg": "12px",
|
|
70
|
+
"--ex-font": '"72", "72full", Arial, sans-serif'
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const ExTheme = {
|
|
74
|
+
// Varsayılan tema — SDK yüklenince çağırılır
|
|
75
|
+
applyDefault() {
|
|
76
|
+
this.apply(DEFAULTS);
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
// Müşteri override — sadece verilen token'lar güncellenir
|
|
80
|
+
apply(tokens = {}) {
|
|
81
|
+
const root = document.documentElement;
|
|
82
|
+
Object.entries(tokens).forEach(([k, v]) => {
|
|
83
|
+
root.style.setProperty(k, v);
|
|
84
|
+
});
|
|
85
|
+
},
|
|
86
|
+
|
|
87
|
+
// Tek token oku
|
|
88
|
+
get(token) {
|
|
89
|
+
return getComputedStyle(document.documentElement)
|
|
90
|
+
.getPropertyValue(token).trim();
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
// Hazır preset temalar
|
|
94
|
+
presets: {
|
|
95
|
+
horizon: {
|
|
96
|
+
"--ex-primary": "#0070f2",
|
|
97
|
+
"--ex-primary-hover": "#005fd4",
|
|
98
|
+
"--ex-radius": "8px"
|
|
99
|
+
},
|
|
100
|
+
dark: {
|
|
101
|
+
"--ex-text": "#e8eaed",
|
|
102
|
+
"--ex-text-muted": "#9aa0a6",
|
|
103
|
+
"--ex-border": "#3c4043"
|
|
104
|
+
},
|
|
105
|
+
rounded: {
|
|
106
|
+
"--ex-radius": "12px",
|
|
107
|
+
"--ex-radius-lg": "20px"
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* ExCore — SDK başlatıcı
|
|
114
|
+
* Kullanım:
|
|
115
|
+
* import ExCore from "@exsdk/ui5"
|
|
116
|
+
* await ExCore.init({ licenseKey: "xxx", theme: "horizon" })
|
|
117
|
+
*/
|
|
118
|
+
|
|
119
|
+
const ExCore = {
|
|
120
|
+
async init({ licenseKey, theme } = {}) {
|
|
121
|
+
// 1. Tema uygula
|
|
122
|
+
ExTheme.applyDefault();
|
|
123
|
+
if (theme && ExTheme.presets[theme]) {
|
|
124
|
+
ExTheme.apply(ExTheme.presets[theme]);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// 2. Lisans doğrula
|
|
128
|
+
const tier = await ExLicense.init(licenseKey);
|
|
129
|
+
|
|
130
|
+
console.log(`[ExSDK] v0.1.0 initialized — tier: ${tier}`);
|
|
131
|
+
return { tier };
|
|
132
|
+
},
|
|
133
|
+
|
|
134
|
+
get license() { return ExLicense; },
|
|
135
|
+
get theme() { return ExTheme; }
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* @exsdk/ui5 — Public API
|
|
140
|
+
*
|
|
141
|
+
* UI5 projesinde kullanım:
|
|
142
|
+
* webapp/control/ klasörüne kopyala, sap.ui.define ile kullan
|
|
143
|
+
*
|
|
144
|
+
* CDN kullanımı:
|
|
145
|
+
* <script src="exsdk.ui5.umd.js"></script>
|
|
146
|
+
* window.ExSDK mevcut olur
|
|
147
|
+
*/
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
const VERSION = "0.1.0";
|
|
151
|
+
const TIER = { FREE: "free", PRO: "pro", ENTERPRISE: "enterprise" };
|
|
152
|
+
|
|
153
|
+
// UI5 Custom Control dosyaları sap.ui.define formatında olduğu için
|
|
154
|
+
// doğrudan Rollup'a girmez — webapp/control/ altına kopyalanır.
|
|
155
|
+
// Aşağıdaki liste hangi dosyaların nereye kopyalanacağını belgeler:
|
|
156
|
+
//
|
|
157
|
+
// ExButton.js → webapp/control/ExButton.js (free)
|
|
158
|
+
// ExTable.js → webapp/control/ExTable.js (free)
|
|
159
|
+
// ExForm.js → webapp/control/ExForm.js (free)
|
|
160
|
+
// ExFileUploader.js → webapp/control/ExFileUploader.js (free)
|
|
161
|
+
// ExKanban.js → webapp/control/ExKanban.js (pro)
|
|
162
|
+
|
|
163
|
+
exports.ExCore = ExCore;
|
|
164
|
+
exports.ExLicense = ExLicense;
|
|
165
|
+
exports.ExTheme = ExTheme;
|
|
166
|
+
exports.TIER = TIER;
|
|
167
|
+
exports.VERSION = VERSION;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.ex-table-wrapper{padding:1rem}.ex-table{background:#fff;border:1px solid #e4e5e7;border-radius:12px;box-shadow:0 1px 4px rgba(0,0,0,.06);font-family:"72","72full",Arial,sans-serif;overflow:hidden}.ex-table-header{align-items:center;background:#fff;border-bottom:1px solid #e4e5e7;display:flex;justify-content:space-between;padding:12px 16px}.ex-table-title{color:#1d2d3e;font-size:14px;font-weight:700}.ex-table-total{background:#f0f4f7;border-radius:20px;color:#556b82;font-size:12px;padding:2px 10px}.ex-table-body{height:400px;overflow:auto;position:relative}.ex-table-body::-webkit-scrollbar{height:6px;width:6px}.ex-table-body::-webkit-scrollbar-track{background:transparent}.ex-table-body::-webkit-scrollbar-thumb{background:#c5cdd6;border-radius:3px}.ex-table-body::-webkit-scrollbar-thumb:hover{background:#8fa3b5}.ex-table-inner{border-collapse:collapse;table-layout:fixed;width:100%}.ex-table-thead th{background:#f5f7f9;border-bottom:2px solid #e4e5e7;overflow:hidden;padding:0;position:sticky;top:0;user-select:none;white-space:nowrap;z-index:2}.ex-th-inner{align-items:center;cursor:pointer;display:flex;gap:4px;padding:10px 14px}.ex-th-label{color:#556b82;flex:1;font-size:12px;font-weight:700;letter-spacing:.4px;text-transform:uppercase}.ex-th-sort{color:#8fa3b5;font-size:11px;transition:color .15s}.ex-table-thead th:hover .ex-th-sort{color:#0070f2}.resize-handle{background:transparent;cursor:col-resize;height:100%;position:absolute;right:0;top:0;transition:background .15s;width:4px}.resize-handle:active,.resize-handle:hover{background:#0070f2}.ex-table-row{border-bottom:1px solid #f0f2f4;transition:background .1s}.ex-table-row:hover{background:#f0f6ff;cursor:pointer}.ex-td{color:#1d2d3e;font-size:14px;overflow:hidden;padding:10px 14px;text-overflow:ellipsis;white-space:nowrap}.ex-td-empty{color:#8fa3b5;font-size:14px;padding:48px 0;text-align:center}.ex-form-wrapper{padding:1rem}.ex-form{background:#fff;border:1px solid #e4e5e7;border-radius:12px;box-shadow:0 1px 4px rgba(0,0,0,.06);font-family:"72","72full",Arial,sans-serif;overflow:hidden}.ex-form-header{border-bottom:1px solid #e4e5e7;padding:14px 20px}.ex-form-title{color:#1d2d3e;font-size:14px;font-weight:700}.ex-form-body{padding:20px}.ex-form-grid{display:grid;gap:16px 24px;grid-template-columns:1fr 1fr}.ex-form-field:has(.ex-form-file-zone),.ex-form-field:has(.ex-form-textarea){grid-column:1/-1}.ex-form-field{display:flex;flex-direction:column;gap:6px}.ex-form-label{color:#556b82;font-size:12px;font-weight:600}.ex-form-required .ex-form-label:after{color:#e54646;content:" *"}.ex-form-input{background:#fff;border:1px solid #c5cdd6;border-radius:8px;box-sizing:border-box;color:#1d2d3e;font-family:inherit;font-size:14px;height:36px;outline:none;padding:0 12px;transition:border-color .15s,box-shadow .15s;width:100%}.ex-form-input:focus{border-color:#0070f2;box-shadow:0 0 0 3px rgba(0,112,242,.12)}.ex-form-textarea{height:90px;padding:10px 12px;resize:vertical}.ex-form-select{appearance:none;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12'%3E%3Cpath fill='%23556b82' d='M6 8 1 3h10z'/%3E%3C/svg%3E");background-position:right 12px center;background-repeat:no-repeat;cursor:pointer;padding-right:32px}.ex-form-checkbox-label,.ex-form-radio-label{align-items:center;color:#1d2d3e;cursor:pointer;display:flex;font-size:14px;gap:8px;margin-bottom:6px}.ex-form-checkbox,.ex-form-radio{display:none}.ex-form-checkbox-custom{background:#fff;border:2px solid #c5cdd6;border-radius:4px;flex-shrink:0;height:18px;position:relative;transition:all .15s;width:18px}.ex-form-checkbox:checked+.ex-form-checkbox-custom{background:#0070f2;border-color:#0070f2}.ex-form-checkbox:checked+.ex-form-checkbox-custom:after{border:2px solid #fff;border-left:none;border-top:none;content:"";height:10px;left:4px;position:absolute;top:1px;transform:rotate(45deg);width:6px}.ex-form-radio-custom{background:#fff;border:2px solid #c5cdd6;border-radius:50%;flex-shrink:0;height:18px;position:relative;transition:all .15s;width:18px}.ex-form-radio:checked+.ex-form-radio-custom{border-color:#0070f2}.ex-form-radio:checked+.ex-form-radio-custom:after{background:#0070f2;border-radius:50%;content:"";height:8px;left:3px;position:absolute;top:3px;width:8px}.ex-form-file-zone{border:2px dashed #c5cdd6;border-radius:10px;cursor:pointer;padding:24px;position:relative;text-align:center;transition:border-color .15s,background .15s}.ex-form-file-drag,.ex-form-file-zone:hover{background:#f0f6ff;border-color:#0070f2}.ex-form-file-input{display:none}.ex-form-file-label{align-items:center;color:#556b82;display:flex;flex-direction:column;font-size:14px;gap:6px;pointer-events:none}.ex-form-file-icon{color:#0070f2;font-size:24px}.ex-form-file-name{color:#0070f2;font-size:12px;font-weight:600}.ex-form-error{color:#e54646;font-size:12px;min-height:16px}.ex-form-field-error .ex-form-input,.ex-form-field-error .ex-form-select,.ex-form-field-error .ex-form-textarea{border-color:#e54646;box-shadow:0 0 0 3px rgba(229,70,70,.1)}.ex-form-footer{background:#fafbfc;border-top:1px solid #e4e5e7;display:flex;gap:10px;justify-content:flex-end;padding:14px 20px}.ex-btn{font-family:inherit;font-size:14px;height:36px;padding:0 20px;transition:all .15s}.ex-btn-primary{background:#0070f2;color:#fff}.ex-btn-primary:hover{background:#0058c4}.ex-btn-primary:disabled{background:#8fa3b5;cursor:not-allowed}.ex-btn-ghost{background:transparent;border:1px solid #c5cdd6;color:#556b82}.ex-btn-ghost:hover{background:#f5f7f9}.ex-form-toast{animation:ex-toast-in .2s ease;border-radius:8px;bottom:20px;box-shadow:0 4px 12px rgba(0,0,0,.12);font-size:14px;font-weight:600;padding:12px 20px;position:absolute;right:20px;z-index:100}.ex-form-toast-success{background:#e6f4ea;color:#1a7f37}.ex-form-toast-error{background:#fde8e8;color:#c0392b}@keyframes ex-toast-in{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.ex-fu-wrapper{padding:1rem}.ex-fu{background:#fff;border:1px solid #e4e5e7;border-radius:12px;box-shadow:0 1px 4px rgba(0,0,0,.06);font-family:"72","72full",Arial,sans-serif;overflow:hidden}.ex-fu-header{align-items:center;border-bottom:1px solid #e4e5e7;display:flex;justify-content:space-between;padding:12px 16px}.ex-fu-title{color:#1d2d3e;font-size:14px;font-weight:700}.ex-fu-meta{color:#8fa3b5;font-size:12px}.ex-fu-zone{border:2px dashed #c5cdd6;border-radius:10px;cursor:pointer;margin:16px;outline:none;transition:border-color .15s,background .15s}.ex-fu-drag,.ex-fu-zone:focus,.ex-fu-zone:hover{background:#f0f6ff;border-color:#0070f2}.ex-fu-zone-inner{align-items:center;display:flex;flex-direction:column;gap:6px;padding:28px 20px;pointer-events:none}.ex-fu-zone-text{color:#1d2d3e;font-size:14px;font-weight:600;margin:0}.ex-fu-zone-sub{color:#8fa3b5;font-size:13px;margin:0}.ex-fu-browse{color:#0070f2;font-weight:600;text-decoration:underline}.ex-fu-input{display:none}.ex-fu-list{display:flex;flex-direction:column;gap:8px;padding:0 16px 16px}.ex-fu-item{align-items:center;background:#fafbfc;border:1px solid #e4e5e7;border-radius:8px;display:flex;gap:12px;padding:10px 12px;transition:border-color .15s}.ex-fu-item-error{background:#fff8f8;border-color:#f5c0c0}.ex-fu-thumb{align-items:center;background:#f0f4f7;border-radius:6px;display:flex;flex-shrink:0;height:44px;justify-content:center;overflow:hidden;width:44px}.ex-fu-preview{height:100%;object-fit:cover;width:100%}.ex-fu-ext{color:#556b82;font-size:11px;font-weight:700;letter-spacing:.5px}.ex-fu-info{display:flex;flex:1;flex-direction:column;gap:4px;min-width:0}.ex-fu-name{color:#1d2d3e;font-size:13px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ex-fu-size{color:#8fa3b5;font-size:12px}.ex-fu-error-msg{color:#e54646;font-size:12px;font-weight:500}.ex-fu-progress-bar{background:#e4e5e7;border-radius:2px;height:4px;overflow:hidden}.ex-fu-progress-fill{background:#0070f2;border-radius:2px;height:100%;transition:width .3s ease}.ex-fu-remove{background:none;border:none;border-radius:4px;color:#8fa3b5;cursor:pointer;flex-shrink:0;font-size:14px;line-height:1;padding:4px 6px;transition:color .15s,background .15s}.ex-fu-remove:hover{background:#fff0f0;color:#e54646}.ex-kb-wrapper{padding:1rem}.ex-kb{background:#f8f9fb;border:1px solid #e4e5e7;border-radius:12px;box-shadow:0 1px 4px rgba(0,0,0,.06);font-family:"72","72full",Arial,sans-serif;overflow:hidden}.ex-kb-header{align-items:center;background:#fff;border-bottom:1px solid #e4e5e7;display:flex;justify-content:space-between;padding:12px 16px}.ex-kb-title{color:#1d2d3e;font-size:14px;font-weight:700}.ex-kb-board{align-items:flex-start;display:flex;gap:12px;min-height:400px;overflow-x:auto;padding:16px}.ex-kb-board::-webkit-scrollbar{height:6px}.ex-kb-board::-webkit-scrollbar-thumb{background:#c5cdd6;border-radius:3px}.ex-kb-lane{background:#fff;border:1px solid #e4e5e7;border-radius:10px;display:flex;flex-direction:column;flex-shrink:0;max-width:260px;min-width:260px}.ex-kb-lane-header{align-items:center;border-bottom:1px solid #f0f2f4;display:flex;justify-content:space-between;padding:10px 14px}.ex-kb-lane-title{color:#1d2d3e;font-size:13px;font-weight:700}.ex-kb-lane-count{background:#f0f4f7;border-radius:20px;color:#556b82;font-size:11px;font-weight:600;padding:1px 8px}.ex-kb-lane-body{display:flex;flex:1;flex-direction:column;gap:8px;min-height:80px;padding:10px;position:relative;transition:background .15s}.ex-kb-lane-over{background:#f0f6ff;border-radius:0 0 10px 10px}.ex-kb-lane-footer{padding:6px 10px 10px}.ex-kb-drop-indicator{background:transparent;border-radius:2px;height:2px;transition:background .15s}.ex-kb-lane-over .ex-kb-drop-indicator{background:#0070f2}.ex-kb-card{background:#fff;border:1px solid #e4e5e7;border-radius:8px;cursor:grab;padding:10px 12px;transition:box-shadow .15s,opacity .15s;user-select:none}.ex-kb-card:hover{box-shadow:0 2px 8px rgba(0,0,0,.1)}.ex-kb-card-dragging{cursor:grabbing;opacity:.4}.ex-kb-card-top{align-items:flex-start;display:flex;gap:8px;justify-content:space-between}.ex-kb-card-title{color:#1d2d3e;flex:1;font-size:13px;font-weight:600;line-height:1.4}.ex-kb-card-desc{color:#8fa3b5;font-size:12px;line-height:1.5;margin:6px 0 0}.ex-kb-card-bottom{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}.ex-kb-priority{border-radius:20px;font-size:11px;font-weight:600;padding:2px 8px}.ex-kb-card-menu{background:none;border:none;border-radius:4px;color:#8fa3b5;cursor:pointer;flex-shrink:0;font-size:16px;line-height:1;padding:0 2px;transition:color .15s,background .15s}.ex-kb-card-menu:hover{background:#f0f2f4;color:#1d2d3e}.ex-kb-card-menu-popup{background:#fff;border:1px solid #e4e5e7;border-radius:8px;box-shadow:0 4px 16px rgba(0,0,0,.12);min-width:160px;overflow:hidden;position:absolute;z-index:50}.ex-kb-menu-item{color:#1d2d3e;cursor:pointer;font-size:13px;padding:10px 16px;transition:background .1s}.ex-kb-menu-item:hover{background:#f5f7f9}.ex-kb-menu-delete:hover{background:#fff0f0;color:#e54646}.ex-kb-btn-ghost{background:none;border:1px dashed #c5cdd6;border-radius:8px;color:#8fa3b5;cursor:pointer;font-family:inherit;font-size:12px;padding:6px 12px;transition:all .15s;width:100%}.ex-kb-btn-ghost:hover{background:#f0f6ff;border-color:#0070f2;color:#0070f2}.ex-kb-btn-primary{background:#0070f2;border:none;border-radius:8px;color:#fff;cursor:pointer;font-family:inherit;font-size:13px;font-weight:600;padding:8px 20px;transition:background .15s}.ex-kb-btn-primary:hover{background:#0058c4}.ex-kb-popup{align-items:center;background:rgba(0,0,0,.35);border-radius:12px;display:flex;inset:0;justify-content:center;position:absolute;z-index:100}.ex-kb-popup-box{background:#fff;border-radius:12px;box-shadow:0 8px 32px rgba(0,0,0,.18);max-width:440px;overflow:hidden;width:100%}.ex-kb-popup-header{align-items:center;border-bottom:1px solid #e4e5e7;color:#1d2d3e;display:flex;font-size:14px;font-weight:700;justify-content:space-between;padding:14px 20px}.ex-kb-popup-close{background:none;border:none;border-radius:4px;color:#8fa3b5;cursor:pointer;font-size:16px;padding:2px 6px}.ex-kb-popup-close:hover{background:#f0f2f4;color:#1d2d3e}.ex-kb-popup-body{display:flex;flex-direction:column;gap:8px;padding:16px 20px}.ex-kb-popup-label{color:#556b82;font-size:12px;font-weight:600;margin-top:4px}.ex-kb-popup-input{border:1px solid #c5cdd6;border-radius:8px;box-sizing:border-box;color:#1d2d3e;font-family:inherit;font-size:14px;height:36px;outline:none;padding:0 12px;transition:border-color .15s;width:100%}.ex-kb-popup-input:focus{border-color:#0070f2}.ex-kb-popup-textarea{height:70px;padding:8px 12px;resize:none}.ex-kb-popup-footer{background:#fafbfc;border-top:1px solid #e4e5e7;display:flex;gap:10px;justify-content:flex-end;padding:12px 20px}.ex-kb-color-picker{display:flex;flex-wrap:wrap;gap:8px}.ex-kb-color-dot{border:2px solid transparent;border-radius:50%;cursor:pointer;height:24px;transition:transform .1s,border-color .1s;width:24px}.ex-kb-color-dot:hover{transform:scale(1.15)}.ex-kb-color-selected{border-color:#1d2d3e!important;transform:scale(1.15)}.ex-kb-detail-badge{background:#f0f4f7;border-radius:20px;color:#556b82;display:inline-block;font-size:12px;font-weight:600;padding:3px 10px}.ex-btn{transition:background .15s ease,color .15s ease,border-color .15s ease,box-shadow .15s ease,transform .1s ease}.ex-btn:not(:disabled):active{transform:scale(.97)}.ex-btn:focus-visible{box-shadow:0 0 0 3px rgba(0,112,242,.3)}.ex-btn--lg{height:44px;padding:0 24px}.ex-btn--icon-only.ex-btn--lg{width:44px}.ex-btn--primary:not(:disabled):hover{background:#0060d0;box-shadow:0 4px 12px rgba(0,112,242,.35)}.ex-btn--secondary{border:1px solid #c5cdd6}.ex-btn--ghost{border:1px solid #0070f2}.ex-btn--ghost:not(:disabled):hover{background:#f0f6ff}.ex-btn--danger:not(:disabled):hover{box-shadow:0 4px 12px rgba(229,70,70,.35)}.ex-btn--danger:focus-visible{box-shadow:0 0 0 3px rgba(229,70,70,.3)}.ex-btn:disabled{opacity:.45}.ex-btn--lg .ex-btn-icon{font-size:17px}.ex-btn-spinner{align-items:center;display:inline-flex;flex-shrink:0;justify-content:center}.ex-btn-spinner svg{animation:ex-spin .7s linear infinite;height:15px;width:15px}.ex-btn--sm .ex-btn-spinner svg{height:13px;width:13px}.ex-btn--lg .ex-btn-spinner svg{height:17px;width:17px}.ex-btn-ripple{animation:ex-ripple .5s ease-out forwards;background:hsla(0,0%,100%,.35)}.ex-btn--ghost .ex-btn-ripple,.ex-btn--secondary .ex-btn-ripple{background:rgba(0,112,242,.15)}.ex-btn-wrapper{display:inline-block}.ex-btn{align-items:center;border:none;border-radius:8px;cursor:pointer;display:inline-flex;font-family:"72","72full",Arial,sans-serif;font-weight:600;gap:7px;justify-content:center;letter-spacing:.01em;outline:none;overflow:hidden;position:relative;transition:background .15s ease,color .15s ease,border-color .15s ease,box-shadow .18s ease,transform .1s ease;user-select:none;white-space:nowrap}.ex-btn:not(:disabled):active{transform:scale(.96)}.ex-btn:focus-visible{box-shadow:0 0 0 3px rgba(0,112,242,.28);outline:none}.ex-btn--sm{border-radius:6px;font-size:12px;gap:5px;height:28px;padding:0 12px}.ex-btn--md{font-size:14px;height:36px;padding:0 18px}.ex-btn--lg{border-radius:10px;font-size:15px;gap:9px;height:46px;padding:0 26px}.ex-btn--icon-only.ex-btn--sm{padding:0;width:28px}.ex-btn--icon-only.ex-btn--md{padding:0;width:36px}.ex-btn--icon-only.ex-btn--lg{padding:0;width:46px}.ex-btn--primary{background:#0070f2;box-shadow:0 1px 2px rgba(0,112,242,.2);color:#fff}.ex-btn--primary:not(:disabled):hover{background:#005fd4;box-shadow:0 4px 14px rgba(0,112,242,.38)}.ex-btn--secondary{background:#f0f4f7;border:1.5px solid #d0d8e0;color:#1d2d3e}.ex-btn--secondary:not(:disabled):hover{background:#e4eaf0;border-color:#8fa3b5;box-shadow:0 2px 8px rgba(0,0,0,.08)}.ex-btn--secondary:focus-visible{box-shadow:0 0 0 3px rgba(100,130,160,.25)}.ex-btn--ghost{background:transparent;border:1.5px solid #0070f2;color:#0070f2}.ex-btn--ghost:not(:disabled):hover{background:#eef5ff;box-shadow:0 2px 8px rgba(0,112,242,.15)}.ex-btn--ghost .ex-btn-ripple{background:rgba(0,112,242,.12)}.ex-btn--danger{background:#e54646;box-shadow:0 1px 2px rgba(229,70,70,.2);color:#fff}.ex-btn--danger:not(:disabled):hover{background:#c73030;box-shadow:0 4px 14px rgba(229,70,70,.38)}.ex-btn--danger:focus-visible{box-shadow:0 0 0 3px rgba(229,70,70,.28)}.ex-btn--pill{background:#0070f2;border-radius:100px;box-shadow:0 1px 2px rgba(0,112,242,.2);color:#fff}.ex-btn--pill:not(:disabled):hover{background:#005fd4;box-shadow:0 4px 14px rgba(0,112,242,.38)}.ex-btn--gradient{background:linear-gradient(135deg,#0070f2,#7c3aed);background-size:200% 200%;border:none;box-shadow:0 2px 8px rgba(124,58,237,.25);color:#fff;transition:box-shadow .18s,transform .1s,background-position .3s}.ex-btn--gradient:not(:disabled):hover{background-position:100%;box-shadow:0 4px 18px rgba(124,58,237,.42)}.ex-btn--gradient:focus-visible{box-shadow:0 0 0 3px rgba(124,58,237,.3)}.ex-btn--gradient .ex-btn-ripple{background:hsla(0,0%,100%,.25)}.ex-btn--glass{backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);background:hsla(0,0%,100%,.18);border:1.5px solid hsla(0,0%,100%,.45);box-shadow:0 2px 12px rgba(0,0,0,.08);color:#1d2d3e}.ex-btn--glass:not(:disabled):hover{background:hsla(0,0%,100%,.3);box-shadow:0 4px 20px rgba(0,0,0,.14)}.ex-btn--glass .ex-btn-ripple{background:hsla(0,0%,100%,.35)}.ex-btn--text-btn{background:transparent;border:none;border-radius:4px;box-shadow:none;color:#0070f2;padding-left:4px;padding-right:4px}.ex-btn--text-btn:not(:disabled):hover{background:#eef5ff;text-decoration:underline}.ex-btn--text-btn .ex-btn-ripple{background:rgba(0,112,242,.1)}.ex-btn:disabled{box-shadow:none!important;cursor:not-allowed;opacity:.42;pointer-events:none;transform:none!important}.ex-btn--loading{cursor:wait;pointer-events:none}.ex-btn--success{background:#0f8c3b!important;box-shadow:0 2px 8px rgba(15,140,59,.3)!important;color:#fff!important}.ex-btn--error{background:#e54646!important;box-shadow:0 2px 8px rgba(229,70,70,.3)!important;color:#fff!important}.ex-btn-icon{align-items:center;display:inline-flex;flex-shrink:0;font-size:15px;justify-content:center;line-height:1}.ex-btn--sm .ex-btn-icon{font-size:13px}.ex-btn--lg .ex-btn-icon{font-size:18px}.ex-btn-spinner-icon svg{animation:ex-spin .65s linear infinite;height:15px;width:15px}.ex-btn--sm .ex-btn-spinner-icon svg{height:13px;width:13px}.ex-btn--lg .ex-btn-spinner-icon svg{height:17px;width:17px}@keyframes ex-spin{to{transform:rotate(1turn)}}.ex-btn-ripple-container{border-radius:inherit;inset:0;overflow:hidden;pointer-events:none;position:absolute}.ex-btn-ripple{animation:ex-ripple .55s ease-out forwards;background:hsla(0,0%,100%,.3);border-radius:50%;pointer-events:none;position:absolute;transform:scale(0)}.ex-btn--secondary .ex-btn-ripple{background:rgba(0,112,242,.1)}@keyframes ex-ripple{to{opacity:0;transform:scale(1)}}.ex-btn-text{pointer-events:none;position:relative;z-index:1}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* @exsdk/ui5 v0.1.0
|
|
3
|
+
* Modern UI Component SDK for SAP Fiori & UI5
|
|
4
|
+
* (c) 2026 ExSDK
|
|
5
|
+
* Released under commercial license — see LICENSE.md
|
|
6
|
+
*/
|
|
7
|
+
const LICENSE_SERVER = "https://license.exsdk.io/v1/verify";
|
|
8
|
+
const LOCAL_KEY = "exsdk_license";
|
|
9
|
+
const CACHE_TTL_MS = 24 * 60 * 60 * 1000;
|
|
10
|
+
|
|
11
|
+
let _tier = "free", _verified = false;
|
|
12
|
+
|
|
13
|
+
const ExLicense = {
|
|
14
|
+
async init(licenseKey) {
|
|
15
|
+
if (!licenseKey) { _tier = "free"; return _tier; }
|
|
16
|
+
const cached = this._getCache(licenseKey);
|
|
17
|
+
if (cached) { _tier = cached.tier; _verified = true; return _tier; }
|
|
18
|
+
try {
|
|
19
|
+
const res = await fetch(LICENSE_SERVER, {
|
|
20
|
+
method: "POST",
|
|
21
|
+
headers: { "Content-Type": "application/json" },
|
|
22
|
+
body: JSON.stringify({ key: licenseKey, domain: window.location.hostname, sdk: "0.1.0" })
|
|
23
|
+
});
|
|
24
|
+
if (!res.ok) throw new Error();
|
|
25
|
+
const data = await res.json();
|
|
26
|
+
_tier = data.tier || "free"; _verified = true;
|
|
27
|
+
this._setCache(licenseKey, _tier);
|
|
28
|
+
} catch {
|
|
29
|
+
console.warn("[ExSDK] License check failed, running in free mode");
|
|
30
|
+
_tier = "free";
|
|
31
|
+
}
|
|
32
|
+
return _tier;
|
|
33
|
+
},
|
|
34
|
+
isRestricted(componentTier) {
|
|
35
|
+
const o = { free: 0, pro: 1, enterprise: 2 };
|
|
36
|
+
return (o[_tier] || 0) < (o[componentTier] || 0);
|
|
37
|
+
},
|
|
38
|
+
getTier() { return _tier; },
|
|
39
|
+
isVerified() { return _verified; },
|
|
40
|
+
isPro() { return _tier === "pro" || _tier === "enterprise"; },
|
|
41
|
+
_getCache(key) {
|
|
42
|
+
try {
|
|
43
|
+
const d = JSON.parse(localStorage.getItem(LOCAL_KEY));
|
|
44
|
+
if (!d || d.key !== key || Date.now() - d.ts > CACHE_TTL_MS) return null;
|
|
45
|
+
return d;
|
|
46
|
+
} catch { return null; }
|
|
47
|
+
},
|
|
48
|
+
_setCache(key, tier) {
|
|
49
|
+
try { localStorage.setItem(LOCAL_KEY, JSON.stringify({ key, tier, ts: Date.now() })); } catch {}
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* ExTheme — CSS token yönetimi
|
|
55
|
+
* Müşteri kendi marka renklerini buradan override eder
|
|
56
|
+
*/
|
|
57
|
+
const DEFAULTS = {
|
|
58
|
+
"--ex-primary": "#0070f2",
|
|
59
|
+
"--ex-primary-hover": "#005fd4",
|
|
60
|
+
"--ex-danger": "#e54646",
|
|
61
|
+
"--ex-success": "#0f8c3b",
|
|
62
|
+
"--ex-warning": "#e8a000",
|
|
63
|
+
"--ex-text": "#1d2d3e",
|
|
64
|
+
"--ex-text-muted": "#556b82",
|
|
65
|
+
"--ex-border": "#e4e5e7",
|
|
66
|
+
"--ex-radius": "8px",
|
|
67
|
+
"--ex-radius-lg": "12px",
|
|
68
|
+
"--ex-font": '"72", "72full", Arial, sans-serif'
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const ExTheme = {
|
|
72
|
+
// Varsayılan tema — SDK yüklenince çağırılır
|
|
73
|
+
applyDefault() {
|
|
74
|
+
this.apply(DEFAULTS);
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
// Müşteri override — sadece verilen token'lar güncellenir
|
|
78
|
+
apply(tokens = {}) {
|
|
79
|
+
const root = document.documentElement;
|
|
80
|
+
Object.entries(tokens).forEach(([k, v]) => {
|
|
81
|
+
root.style.setProperty(k, v);
|
|
82
|
+
});
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
// Tek token oku
|
|
86
|
+
get(token) {
|
|
87
|
+
return getComputedStyle(document.documentElement)
|
|
88
|
+
.getPropertyValue(token).trim();
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
// Hazır preset temalar
|
|
92
|
+
presets: {
|
|
93
|
+
horizon: {
|
|
94
|
+
"--ex-primary": "#0070f2",
|
|
95
|
+
"--ex-primary-hover": "#005fd4",
|
|
96
|
+
"--ex-radius": "8px"
|
|
97
|
+
},
|
|
98
|
+
dark: {
|
|
99
|
+
"--ex-text": "#e8eaed",
|
|
100
|
+
"--ex-text-muted": "#9aa0a6",
|
|
101
|
+
"--ex-border": "#3c4043"
|
|
102
|
+
},
|
|
103
|
+
rounded: {
|
|
104
|
+
"--ex-radius": "12px",
|
|
105
|
+
"--ex-radius-lg": "20px"
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* ExCore — SDK başlatıcı
|
|
112
|
+
* Kullanım:
|
|
113
|
+
* import ExCore from "@exsdk/ui5"
|
|
114
|
+
* await ExCore.init({ licenseKey: "xxx", theme: "horizon" })
|
|
115
|
+
*/
|
|
116
|
+
|
|
117
|
+
const ExCore = {
|
|
118
|
+
async init({ licenseKey, theme } = {}) {
|
|
119
|
+
// 1. Tema uygula
|
|
120
|
+
ExTheme.applyDefault();
|
|
121
|
+
if (theme && ExTheme.presets[theme]) {
|
|
122
|
+
ExTheme.apply(ExTheme.presets[theme]);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// 2. Lisans doğrula
|
|
126
|
+
const tier = await ExLicense.init(licenseKey);
|
|
127
|
+
|
|
128
|
+
console.log(`[ExSDK] v0.1.0 initialized — tier: ${tier}`);
|
|
129
|
+
return { tier };
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
get license() { return ExLicense; },
|
|
133
|
+
get theme() { return ExTheme; }
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* @exsdk/ui5 — Public API
|
|
138
|
+
*
|
|
139
|
+
* UI5 projesinde kullanım:
|
|
140
|
+
* webapp/control/ klasörüne kopyala, sap.ui.define ile kullan
|
|
141
|
+
*
|
|
142
|
+
* CDN kullanımı:
|
|
143
|
+
* <script src="exsdk.ui5.umd.js"></script>
|
|
144
|
+
* window.ExSDK mevcut olur
|
|
145
|
+
*/
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
const VERSION = "0.1.0";
|
|
149
|
+
const TIER = { FREE: "free", PRO: "pro", ENTERPRISE: "enterprise" };
|
|
150
|
+
|
|
151
|
+
// UI5 Custom Control dosyaları sap.ui.define formatında olduğu için
|
|
152
|
+
// doğrudan Rollup'a girmez — webapp/control/ altına kopyalanır.
|
|
153
|
+
// Aşağıdaki liste hangi dosyaların nereye kopyalanacağını belgeler:
|
|
154
|
+
//
|
|
155
|
+
// ExButton.js → webapp/control/ExButton.js (free)
|
|
156
|
+
// ExTable.js → webapp/control/ExTable.js (free)
|
|
157
|
+
// ExForm.js → webapp/control/ExForm.js (free)
|
|
158
|
+
// ExFileUploader.js → webapp/control/ExFileUploader.js (free)
|
|
159
|
+
// ExKanban.js → webapp/control/ExKanban.js (pro)
|
|
160
|
+
|
|
161
|
+
export { ExCore, ExLicense, ExTheme, TIER, VERSION };
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* @exsdk/ui5 v0.1.0
|
|
3
|
+
* Modern UI Component SDK for SAP Fiori & UI5
|
|
4
|
+
* (c) 2026 ExSDK
|
|
5
|
+
* Released under commercial license — see LICENSE.md
|
|
6
|
+
*/
|
|
7
|
+
(function (global, factory) {
|
|
8
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
9
|
+
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
|
10
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ExSDK = {}));
|
|
11
|
+
})(this, (function (exports) { 'use strict';
|
|
12
|
+
|
|
13
|
+
const LICENSE_SERVER = "https://license.exsdk.io/v1/verify";
|
|
14
|
+
const LOCAL_KEY = "exsdk_license";
|
|
15
|
+
const CACHE_TTL_MS = 24 * 60 * 60 * 1000;
|
|
16
|
+
|
|
17
|
+
let _tier = "free", _verified = false;
|
|
18
|
+
|
|
19
|
+
const ExLicense = {
|
|
20
|
+
async init(licenseKey) {
|
|
21
|
+
if (!licenseKey) { _tier = "free"; return _tier; }
|
|
22
|
+
const cached = this._getCache(licenseKey);
|
|
23
|
+
if (cached) { _tier = cached.tier; _verified = true; return _tier; }
|
|
24
|
+
try {
|
|
25
|
+
const res = await fetch(LICENSE_SERVER, {
|
|
26
|
+
method: "POST",
|
|
27
|
+
headers: { "Content-Type": "application/json" },
|
|
28
|
+
body: JSON.stringify({ key: licenseKey, domain: window.location.hostname, sdk: "0.1.0" })
|
|
29
|
+
});
|
|
30
|
+
if (!res.ok) throw new Error();
|
|
31
|
+
const data = await res.json();
|
|
32
|
+
_tier = data.tier || "free"; _verified = true;
|
|
33
|
+
this._setCache(licenseKey, _tier);
|
|
34
|
+
} catch {
|
|
35
|
+
console.warn("[ExSDK] License check failed, running in free mode");
|
|
36
|
+
_tier = "free";
|
|
37
|
+
}
|
|
38
|
+
return _tier;
|
|
39
|
+
},
|
|
40
|
+
isRestricted(componentTier) {
|
|
41
|
+
const o = { free: 0, pro: 1, enterprise: 2 };
|
|
42
|
+
return (o[_tier] || 0) < (o[componentTier] || 0);
|
|
43
|
+
},
|
|
44
|
+
getTier() { return _tier; },
|
|
45
|
+
isVerified() { return _verified; },
|
|
46
|
+
isPro() { return _tier === "pro" || _tier === "enterprise"; },
|
|
47
|
+
_getCache(key) {
|
|
48
|
+
try {
|
|
49
|
+
const d = JSON.parse(localStorage.getItem(LOCAL_KEY));
|
|
50
|
+
if (!d || d.key !== key || Date.now() - d.ts > CACHE_TTL_MS) return null;
|
|
51
|
+
return d;
|
|
52
|
+
} catch { return null; }
|
|
53
|
+
},
|
|
54
|
+
_setCache(key, tier) {
|
|
55
|
+
try { localStorage.setItem(LOCAL_KEY, JSON.stringify({ key, tier, ts: Date.now() })); } catch {}
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* ExTheme — CSS token yönetimi
|
|
61
|
+
* Müşteri kendi marka renklerini buradan override eder
|
|
62
|
+
*/
|
|
63
|
+
const DEFAULTS = {
|
|
64
|
+
"--ex-primary": "#0070f2",
|
|
65
|
+
"--ex-primary-hover": "#005fd4",
|
|
66
|
+
"--ex-danger": "#e54646",
|
|
67
|
+
"--ex-success": "#0f8c3b",
|
|
68
|
+
"--ex-warning": "#e8a000",
|
|
69
|
+
"--ex-text": "#1d2d3e",
|
|
70
|
+
"--ex-text-muted": "#556b82",
|
|
71
|
+
"--ex-border": "#e4e5e7",
|
|
72
|
+
"--ex-radius": "8px",
|
|
73
|
+
"--ex-radius-lg": "12px",
|
|
74
|
+
"--ex-font": '"72", "72full", Arial, sans-serif'
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const ExTheme = {
|
|
78
|
+
// Varsayılan tema — SDK yüklenince çağırılır
|
|
79
|
+
applyDefault() {
|
|
80
|
+
this.apply(DEFAULTS);
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
// Müşteri override — sadece verilen token'lar güncellenir
|
|
84
|
+
apply(tokens = {}) {
|
|
85
|
+
const root = document.documentElement;
|
|
86
|
+
Object.entries(tokens).forEach(([k, v]) => {
|
|
87
|
+
root.style.setProperty(k, v);
|
|
88
|
+
});
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
// Tek token oku
|
|
92
|
+
get(token) {
|
|
93
|
+
return getComputedStyle(document.documentElement)
|
|
94
|
+
.getPropertyValue(token).trim();
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
// Hazır preset temalar
|
|
98
|
+
presets: {
|
|
99
|
+
horizon: {
|
|
100
|
+
"--ex-primary": "#0070f2",
|
|
101
|
+
"--ex-primary-hover": "#005fd4",
|
|
102
|
+
"--ex-radius": "8px"
|
|
103
|
+
},
|
|
104
|
+
dark: {
|
|
105
|
+
"--ex-text": "#e8eaed",
|
|
106
|
+
"--ex-text-muted": "#9aa0a6",
|
|
107
|
+
"--ex-border": "#3c4043"
|
|
108
|
+
},
|
|
109
|
+
rounded: {
|
|
110
|
+
"--ex-radius": "12px",
|
|
111
|
+
"--ex-radius-lg": "20px"
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* ExCore — SDK başlatıcı
|
|
118
|
+
* Kullanım:
|
|
119
|
+
* import ExCore from "@exsdk/ui5"
|
|
120
|
+
* await ExCore.init({ licenseKey: "xxx", theme: "horizon" })
|
|
121
|
+
*/
|
|
122
|
+
|
|
123
|
+
const ExCore = {
|
|
124
|
+
async init({ licenseKey, theme } = {}) {
|
|
125
|
+
// 1. Tema uygula
|
|
126
|
+
ExTheme.applyDefault();
|
|
127
|
+
if (theme && ExTheme.presets[theme]) {
|
|
128
|
+
ExTheme.apply(ExTheme.presets[theme]);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// 2. Lisans doğrula
|
|
132
|
+
const tier = await ExLicense.init(licenseKey);
|
|
133
|
+
|
|
134
|
+
console.log(`[ExSDK] v0.1.0 initialized — tier: ${tier}`);
|
|
135
|
+
return { tier };
|
|
136
|
+
},
|
|
137
|
+
|
|
138
|
+
get license() { return ExLicense; },
|
|
139
|
+
get theme() { return ExTheme; }
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* @exsdk/ui5 — Public API
|
|
144
|
+
*
|
|
145
|
+
* UI5 projesinde kullanım:
|
|
146
|
+
* webapp/control/ klasörüne kopyala, sap.ui.define ile kullan
|
|
147
|
+
*
|
|
148
|
+
* CDN kullanımı:
|
|
149
|
+
* <script src="exsdk.ui5.umd.js"></script>
|
|
150
|
+
* window.ExSDK mevcut olur
|
|
151
|
+
*/
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
const VERSION = "0.1.0";
|
|
155
|
+
const TIER = { FREE: "free", PRO: "pro", ENTERPRISE: "enterprise" };
|
|
156
|
+
|
|
157
|
+
// UI5 Custom Control dosyaları sap.ui.define formatında olduğu için
|
|
158
|
+
// doğrudan Rollup'a girmez — webapp/control/ altına kopyalanır.
|
|
159
|
+
// Aşağıdaki liste hangi dosyaların nereye kopyalanacağını belgeler:
|
|
160
|
+
//
|
|
161
|
+
// ExButton.js → webapp/control/ExButton.js (free)
|
|
162
|
+
// ExTable.js → webapp/control/ExTable.js (free)
|
|
163
|
+
// ExForm.js → webapp/control/ExForm.js (free)
|
|
164
|
+
// ExFileUploader.js → webapp/control/ExFileUploader.js (free)
|
|
165
|
+
// ExKanban.js → webapp/control/ExKanban.js (pro)
|
|
166
|
+
|
|
167
|
+
exports.ExCore = ExCore;
|
|
168
|
+
exports.ExLicense = ExLicense;
|
|
169
|
+
exports.ExTheme = ExTheme;
|
|
170
|
+
exports.TIER = TIER;
|
|
171
|
+
exports.VERSION = VERSION;
|
|
172
|
+
|
|
173
|
+
}));
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "exsdk-ui5",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Modern UI component SDK for SAP Fiori & UI5 — beautiful, fast, framework-independent",
|
|
5
|
+
"author": "ExSDK",
|
|
6
|
+
"license": "SEE LICENSE IN LICENSE.md",
|
|
7
|
+
"main": "dist/exsdk.ui5.cjs.js",
|
|
8
|
+
"module": "dist/exsdk.ui5.esm.js",
|
|
9
|
+
"browser": "dist/exsdk.ui5.umd.js",
|
|
10
|
+
"style": "dist/exsdk.ui5.css",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": "./dist/exsdk.ui5.esm.js",
|
|
14
|
+
"require": "./dist/exsdk.ui5.cjs.js"
|
|
15
|
+
},
|
|
16
|
+
"./css": "./dist/exsdk.ui5.css"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"ui5-wrapper",
|
|
21
|
+
"README.md",
|
|
22
|
+
"LICENSE.md"
|
|
23
|
+
],
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "rollup -c",
|
|
26
|
+
"watch": "rollup -c --watch",
|
|
27
|
+
"version": "node scripts/version.js"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"rollup": "^4.0.0",
|
|
31
|
+
"rollup-plugin-postcss": "^4.0.2",
|
|
32
|
+
"@rollup/plugin-node-resolve": "^15.0.0",
|
|
33
|
+
"postcss": "^8.4.0"
|
|
34
|
+
},
|
|
35
|
+
"keywords": [
|
|
36
|
+
"sap", "ui5", "fiori", "sdk", "components",
|
|
37
|
+
"table", "form", "kanban", "button"
|
|
38
|
+
],
|
|
39
|
+
"repository": {
|
|
40
|
+
"type": "git",
|
|
41
|
+
"url": "https://github.com/exsdk/ui5"
|
|
42
|
+
}
|
|
43
|
+
}
|