@ttdk-design-system/library-svelte 0.0.0-stage → 1.0.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/AI_GUIDE.md +6518 -0
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.js +2 -0
- package/dist/core/tailwind-preset.cjs +62 -0
- package/dist/core/tailwind-preset.d.cts +63 -0
- package/dist/core/tailwind-preset.d.ts +74 -0
- package/dist/core/tailwind-preset.js +79 -0
- package/dist/core/theme/tokens.css +663 -0
- package/dist/core/types.d.ts +152 -0
- package/dist/core/types.js +735 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +15 -0
- package/dist/tailwind-preset.cjs +62 -0
- package/dist/tailwind-preset.d.cts +63 -0
- package/dist/tailwind-preset.d.ts +74 -0
- package/dist/tailwind-preset.js +79 -0
- package/dist/types.d.ts +1 -0
- package/dist/types.js +1 -0
- package/dist/web/accordion/AI_GUIDE.md +149 -0
- package/dist/web/accordion/accordion.css +1 -0
- package/dist/web/accordion/accordion.svelte +217 -0
- package/dist/web/accordion/accordion.svelte.d.ts +224 -0
- package/dist/web/accordion/index.d.ts +2 -0
- package/dist/web/accordion/index.js +2 -0
- package/dist/web/accordion/manifest.json +351 -0
- package/dist/web/alert/AI_GUIDE.md +139 -0
- package/dist/web/alert/alert.css +1 -0
- package/dist/web/alert/alert.svelte +175 -0
- package/dist/web/alert/alert.svelte.d.ts +165 -0
- package/dist/web/alert/index.d.ts +2 -0
- package/dist/web/alert/index.js +2 -0
- package/dist/web/alert/manifest.json +240 -0
- package/dist/web/avatar/AI_GUIDE.md +118 -0
- package/dist/web/avatar/avatar.css +1 -0
- package/dist/web/avatar/avatar.svelte +108 -0
- package/dist/web/avatar/avatar.svelte.d.ts +147 -0
- package/dist/web/avatar/index.d.ts +2 -0
- package/dist/web/avatar/index.js +2 -0
- package/dist/web/avatar/manifest.json +195 -0
- package/dist/web/badge/AI_GUIDE.md +94 -0
- package/dist/web/badge/badge.css +1 -0
- package/dist/web/badge/badge.svelte +50 -0
- package/dist/web/badge/badge.svelte.d.ts +111 -0
- package/dist/web/badge/index.d.ts +2 -0
- package/dist/web/badge/index.js +2 -0
- package/dist/web/badge/manifest.json +141 -0
- package/dist/web/banner/AI_GUIDE.md +130 -0
- package/dist/web/banner/banner.css +1 -0
- package/dist/web/banner/banner.svelte +180 -0
- package/dist/web/banner/banner.svelte.d.ts +172 -0
- package/dist/web/banner/index.d.ts +2 -0
- package/dist/web/banner/index.js +2 -0
- package/dist/web/banner/manifest.json +240 -0
- package/dist/web/breadcrumb/AI_GUIDE.md +120 -0
- package/dist/web/breadcrumb/breadcrumb.css +1 -0
- package/dist/web/breadcrumb/breadcrumb.svelte +168 -0
- package/dist/web/breadcrumb/breadcrumb.svelte.d.ts +141 -0
- package/dist/web/breadcrumb/index.d.ts +2 -0
- package/dist/web/breadcrumb/index.js +2 -0
- package/dist/web/breadcrumb/manifest.json +225 -0
- package/dist/web/button/AI_GUIDE.md +121 -0
- package/dist/web/button/button.css +1 -0
- package/dist/web/button/button.svelte +154 -0
- package/dist/web/button/button.svelte.d.ts +159 -0
- package/dist/web/button/index.d.ts +2 -0
- package/dist/web/button/index.js +2 -0
- package/dist/web/button/manifest.json +177 -0
- package/dist/web/calendar/AI_GUIDE.md +151 -0
- package/dist/web/calendar/calendar.css +1 -0
- package/dist/web/calendar/calendar.svelte +1091 -0
- package/dist/web/calendar/calendar.svelte.d.ts +268 -0
- package/dist/web/calendar/index.d.ts +2 -0
- package/dist/web/calendar/index.js +2 -0
- package/dist/web/calendar/manifest.json +470 -0
- package/dist/web/card/AI_GUIDE.md +133 -0
- package/dist/web/card/card.css +1 -0
- package/dist/web/card/card.svelte +217 -0
- package/dist/web/card/card.svelte.d.ts +242 -0
- package/dist/web/card/index.d.ts +2 -0
- package/dist/web/card/index.js +2 -0
- package/dist/web/card/manifest.json +357 -0
- package/dist/web/checkbox/AI_GUIDE.md +146 -0
- package/dist/web/checkbox/checkbox.css +1 -0
- package/dist/web/checkbox/checkbox.svelte +131 -0
- package/dist/web/checkbox/checkbox.svelte.d.ts +199 -0
- package/dist/web/checkbox/index.d.ts +2 -0
- package/dist/web/checkbox/index.js +2 -0
- package/dist/web/checkbox/manifest.json +294 -0
- package/dist/web/chip/AI_GUIDE.md +186 -0
- package/dist/web/chip/chip.css +1 -0
- package/dist/web/chip/chip.svelte +113 -0
- package/dist/web/chip/chip.svelte.d.ts +145 -0
- package/dist/web/chip/index.d.ts +2 -0
- package/dist/web/chip/index.js +2 -0
- package/dist/web/chip/manifest.json +186 -0
- package/dist/web/dropdown/AI_GUIDE.md +167 -0
- package/dist/web/dropdown/dropdown.css +1 -0
- package/dist/web/dropdown/dropdown.svelte +844 -0
- package/dist/web/dropdown/dropdown.svelte.d.ts +361 -0
- package/dist/web/dropdown/index.d.ts +2 -0
- package/dist/web/dropdown/index.js +2 -0
- package/dist/web/dropdown/manifest.json +576 -0
- package/dist/web/flex/AI_GUIDE.md +113 -0
- package/dist/web/flex/flex-item.svelte +37 -0
- package/dist/web/flex/flex-item.svelte.d.ts +96 -0
- package/dist/web/flex/flex.css +1 -0
- package/dist/web/flex/flex.svelte +39 -0
- package/dist/web/flex/flex.svelte.d.ts +104 -0
- package/dist/web/flex/index.d.ts +3 -0
- package/dist/web/flex/index.js +3 -0
- package/dist/web/flex/manifest.json +162 -0
- package/dist/web/form/index.d.ts +1 -0
- package/dist/web/form/index.js +2 -0
- package/dist/web/grid/AI_GUIDE.md +112 -0
- package/dist/web/grid/grid-item.svelte +41 -0
- package/dist/web/grid/grid-item.svelte.d.ts +112 -0
- package/dist/web/grid/grid.css +1 -0
- package/dist/web/grid/grid.svelte +37 -0
- package/dist/web/grid/grid.svelte.d.ts +96 -0
- package/dist/web/grid/index.d.ts +3 -0
- package/dist/web/grid/index.js +3 -0
- package/dist/web/grid/manifest.json +153 -0
- package/dist/web/index.d.ts +58 -0
- package/dist/web/index.js +57 -0
- package/dist/web/input/AI_GUIDE.md +159 -0
- package/dist/web/input/index.d.ts +2 -0
- package/dist/web/input/index.js +2 -0
- package/dist/web/input/input.css +1 -0
- package/dist/web/input/input.svelte +283 -0
- package/dist/web/input/input.svelte.d.ts +283 -0
- package/dist/web/input/manifest.json +465 -0
- package/dist/web/input-number/AI_GUIDE.md +164 -0
- package/dist/web/input-number/index.d.ts +2 -0
- package/dist/web/input-number/index.js +2 -0
- package/dist/web/input-number/input-number.css +1 -0
- package/dist/web/input-number/input-number.svelte +783 -0
- package/dist/web/input-number/input-number.svelte.d.ts +352 -0
- package/dist/web/input-number/manifest.json +575 -0
- package/dist/web/modal/AI_GUIDE.md +171 -0
- package/dist/web/modal/index.d.ts +2 -0
- package/dist/web/modal/index.js +2 -0
- package/dist/web/modal/manifest.json +375 -0
- package/dist/web/modal/modal.css +1 -0
- package/dist/web/modal/modal.svelte +333 -0
- package/dist/web/modal/modal.svelte.d.ts +231 -0
- package/dist/web/pagination/AI_GUIDE.md +148 -0
- package/dist/web/pagination/index.d.ts +19 -0
- package/dist/web/pagination/index.js +19 -0
- package/dist/web/pagination/manifest.json +432 -0
- package/dist/web/pagination/pagination-content.svelte +25 -0
- package/dist/web/pagination/pagination-content.svelte.d.ts +36 -0
- package/dist/web/pagination/pagination-ellipsis.svelte +38 -0
- package/dist/web/pagination/pagination-ellipsis.svelte.d.ts +35 -0
- package/dist/web/pagination/pagination-first.svelte +105 -0
- package/dist/web/pagination/pagination-first.svelte.d.ts +74 -0
- package/dist/web/pagination/pagination-item.svelte +25 -0
- package/dist/web/pagination/pagination-item.svelte.d.ts +36 -0
- package/dist/web/pagination/pagination-last.svelte +105 -0
- package/dist/web/pagination/pagination-last.svelte.d.ts +74 -0
- package/dist/web/pagination/pagination-link.svelte +67 -0
- package/dist/web/pagination/pagination-link.svelte.d.ts +69 -0
- package/dist/web/pagination/pagination-next.svelte +99 -0
- package/dist/web/pagination/pagination-next.svelte.d.ts +75 -0
- package/dist/web/pagination/pagination-previous.svelte +99 -0
- package/dist/web/pagination/pagination-previous.svelte.d.ts +75 -0
- package/dist/web/pagination/pagination.css +1 -0
- package/dist/web/pagination/pagination.svelte +471 -0
- package/dist/web/pagination/pagination.svelte.d.ts +256 -0
- package/dist/web/popover/AI_GUIDE.md +163 -0
- package/dist/web/popover/index.d.ts +3 -0
- package/dist/web/popover/index.js +3 -0
- package/dist/web/popover/manifest.json +396 -0
- package/dist/web/popover/popover.css +1 -0
- package/dist/web/popover/popover.svelte +497 -0
- package/dist/web/popover/popover.svelte.d.ts +116 -0
- package/dist/web/radio/AI_GUIDE.md +155 -0
- package/dist/web/radio/index.d.ts +2 -0
- package/dist/web/radio/index.js +2 -0
- package/dist/web/radio/manifest.json +294 -0
- package/dist/web/radio/radio.css +1 -0
- package/dist/web/radio/radio.svelte +123 -0
- package/dist/web/radio/radio.svelte.d.ts +192 -0
- package/dist/web/selectbox/AI_GUIDE.md +216 -0
- package/dist/web/selectbox/index.d.ts +2 -0
- package/dist/web/selectbox/index.js +2 -0
- package/dist/web/selectbox/manifest.json +477 -0
- package/dist/web/selectbox/selectbox.css +1 -0
- package/dist/web/selectbox/selectbox.svelte +704 -0
- package/dist/web/selectbox/selectbox.svelte.d.ts +296 -0
- package/dist/web/sonner/AI_GUIDE.md +98 -0
- package/dist/web/sonner/index.d.ts +46 -0
- package/dist/web/sonner/index.js +64 -0
- package/dist/web/sonner/manifest.json +132 -0
- package/dist/web/sonner/sonner.css +1 -0
- package/dist/web/sonner/sonner.svelte +85 -0
- package/dist/web/sonner/sonner.svelte.d.ts +105 -0
- package/dist/web/table/AI_GUIDE.md +145 -0
- package/dist/web/table/index.d.ts +21 -0
- package/dist/web/table/index.js +22 -0
- package/dist/web/table/manifest.json +168 -0
- package/dist/web/table/table-body.svelte +23 -0
- package/dist/web/table/table-body.svelte.d.ts +36 -0
- package/dist/web/table/table-caption.svelte +23 -0
- package/dist/web/table/table-caption.svelte.d.ts +36 -0
- package/dist/web/table/table-cell.svelte +35 -0
- package/dist/web/table/table-cell.svelte.d.ts +57 -0
- package/dist/web/table/table-empty.svelte +56 -0
- package/dist/web/table/table-empty.svelte.d.ts +65 -0
- package/dist/web/table/table-footer.svelte +23 -0
- package/dist/web/table/table-footer.svelte.d.ts +36 -0
- package/dist/web/table/table-head.svelte +39 -0
- package/dist/web/table/table-head.svelte.d.ts +58 -0
- package/dist/web/table/table-header.svelte +23 -0
- package/dist/web/table/table-header.svelte.d.ts +36 -0
- package/dist/web/table/table-row.svelte +33 -0
- package/dist/web/table/table-row.svelte.d.ts +52 -0
- package/dist/web/table/table.css +1 -0
- package/dist/web/table/table.svelte +178 -0
- package/dist/web/table/table.svelte.d.ts +120 -0
- package/dist/web/tabs/AI_GUIDE.md +150 -0
- package/dist/web/tabs/index.d.ts +2 -0
- package/dist/web/tabs/index.js +2 -0
- package/dist/web/tabs/manifest.json +315 -0
- package/dist/web/tabs/tabs.css +1 -0
- package/dist/web/tabs/tabs.svelte +138 -0
- package/dist/web/tabs/tabs.svelte.d.ts +204 -0
- package/dist/web/text/AI_GUIDE.md +129 -0
- package/dist/web/text/index.d.ts +2 -0
- package/dist/web/text/index.js +2 -0
- package/dist/web/text/manifest.json +195 -0
- package/dist/web/text/text.css +1 -0
- package/dist/web/text/text.svelte +515 -0
- package/dist/web/text/text.svelte.d.ts +168 -0
- package/dist/web/textarea/AI_GUIDE.md +141 -0
- package/dist/web/textarea/index.d.ts +2 -0
- package/dist/web/textarea/index.js +2 -0
- package/dist/web/textarea/manifest.json +438 -0
- package/dist/web/textarea/textarea.css +1 -0
- package/dist/web/textarea/textarea.svelte +224 -0
- package/dist/web/textarea/textarea.svelte.d.ts +274 -0
- package/dist/web/tooltip/AI_GUIDE.md +110 -0
- package/dist/web/tooltip/index.d.ts +2 -0
- package/dist/web/tooltip/index.js +2 -0
- package/dist/web/tooltip/manifest.json +222 -0
- package/dist/web/tooltip/tooltip.css +1 -0
- package/dist/web/tooltip/tooltip.svelte +292 -0
- package/dist/web/tooltip/tooltip.svelte.d.ts +140 -0
- package/dist/webview/bottomsheet/AI_GUIDE.md +141 -0
- package/dist/webview/bottomsheet/bottomsheet.css +1 -0
- package/dist/webview/bottomsheet/bottomsheet.svelte +462 -0
- package/dist/webview/bottomsheet/bottomsheet.svelte.d.ts +200 -0
- package/dist/webview/bottomsheet/index.d.ts +4 -0
- package/dist/webview/bottomsheet/index.js +3 -0
- package/dist/webview/bottomsheet/manifest.json +377 -0
- package/dist/webview/button/AI_GUIDE.md +79 -0
- package/dist/webview/button/button-ios.css +1 -0
- package/dist/webview/button/button-ios.svelte +58 -0
- package/dist/webview/button/button-ios.svelte.d.ts +114 -0
- package/dist/webview/button/button-material.css +1 -0
- package/dist/webview/button/button-material.svelte +58 -0
- package/dist/webview/button/button-material.svelte.d.ts +114 -0
- package/dist/webview/button/index.d.ts +6 -0
- package/dist/webview/button/index.js +4 -0
- package/dist/webview/button/manifest.json +148 -0
- package/dist/webview/index.d.ts +6 -0
- package/dist/webview/index.js +6 -0
- package/llms.txt +6518 -0
- package/package.json +709 -4
- package/ttdk-manifest.json +10188 -0
- package/README.md +0 -3
|
@@ -0,0 +1,735 @@
|
|
|
1
|
+
export const ResponsiveBreakpoints = {};
|
|
2
|
+
export const UiProps = {};
|
|
3
|
+
/**
|
|
4
|
+
* Helper to build responsive CSS custom properties from a ResponsiveUiProps object.
|
|
5
|
+
*/
|
|
6
|
+
export function buildResponsiveVars(ui, keyMap) {
|
|
7
|
+
if (!ui)
|
|
8
|
+
return {};
|
|
9
|
+
const styles = {};
|
|
10
|
+
const breakpoints = ['sm', 'lt_sm', 'md', 'lt_md', 'lg', 'lt_lg', 'xl', 'lt_xl'];
|
|
11
|
+
// Process default / base level
|
|
12
|
+
for (const [uiKey, cssVar] of Object.entries(keyMap)) {
|
|
13
|
+
if (ui[uiKey] !== undefined) {
|
|
14
|
+
styles[cssVar] = String(ui[uiKey]);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
// Process each breakpoint
|
|
18
|
+
for (const bp of breakpoints) {
|
|
19
|
+
const bpObj = ui[bp];
|
|
20
|
+
if (bpObj && typeof bpObj === 'object') {
|
|
21
|
+
for (const [uiKey, cssVar] of Object.entries(keyMap)) {
|
|
22
|
+
if (bpObj[uiKey] !== undefined) {
|
|
23
|
+
const bpSuffix = bp.replace('_', '-');
|
|
24
|
+
styles[`${cssVar}-${bpSuffix}`] = String(bpObj[uiKey]);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return styles;
|
|
30
|
+
}
|
|
31
|
+
const PSEUDOS = ['hover', 'active', 'focus', 'disabled', 'dark'];
|
|
32
|
+
const BREAKPOINTS = ['sm', 'lt_sm', 'lt-sm', 'md', 'lt_md', 'lt-md', 'lg', 'lt_lg', 'lt-lg', 'xl', 'lt_xl', 'lt-xl', '2xl'];
|
|
33
|
+
const BREAKPOINT_QUERIES = {
|
|
34
|
+
sm: '(min-width: 640px)',
|
|
35
|
+
lt_sm: '(max-width: 639px)',
|
|
36
|
+
'lt-sm': '(max-width: 639px)',
|
|
37
|
+
md: '(min-width: 768px)',
|
|
38
|
+
lt_md: '(max-width: 767px)',
|
|
39
|
+
'lt-md': '(max-width: 767px)',
|
|
40
|
+
lg: '(min-width: 1024px)',
|
|
41
|
+
lt_lg: '(max-width: 1023px)',
|
|
42
|
+
'lt-lg': '(max-width: 1023px)',
|
|
43
|
+
xl: '(min-width: 1280px)',
|
|
44
|
+
lt_xl: '(max-width: 1279px)',
|
|
45
|
+
'lt-xl': '(max-width: 1279px)',
|
|
46
|
+
'2xl': '(min-width: 1536px)',
|
|
47
|
+
};
|
|
48
|
+
const BUCKET_ORDER = [
|
|
49
|
+
'pseudos',
|
|
50
|
+
'lt_xl',
|
|
51
|
+
'lt-xl',
|
|
52
|
+
'lt_lg',
|
|
53
|
+
'lt-lg',
|
|
54
|
+
'lt_md',
|
|
55
|
+
'lt-md',
|
|
56
|
+
'lt_sm',
|
|
57
|
+
'lt-sm',
|
|
58
|
+
'sm',
|
|
59
|
+
'md',
|
|
60
|
+
'lg',
|
|
61
|
+
'xl',
|
|
62
|
+
'2xl',
|
|
63
|
+
];
|
|
64
|
+
/** Convert camelCase ke kebab-case: backgroundColor → background-color */
|
|
65
|
+
function toKebab(str) {
|
|
66
|
+
return str.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);
|
|
67
|
+
}
|
|
68
|
+
/** Membersihkan akhiran !important jika user tidak sengaja menyertakannya di string nilai */
|
|
69
|
+
export function cleanUiValue(v) {
|
|
70
|
+
if (typeof v === 'string') {
|
|
71
|
+
return v.replace(/\s*!important\s*$/i, '').trim();
|
|
72
|
+
}
|
|
73
|
+
return String(v);
|
|
74
|
+
}
|
|
75
|
+
function resolveCssProperty(key) {
|
|
76
|
+
if (key === 'bg')
|
|
77
|
+
return 'background-color';
|
|
78
|
+
if (key === 'size')
|
|
79
|
+
return 'font-size';
|
|
80
|
+
if (key === 'weight')
|
|
81
|
+
return 'font-weight';
|
|
82
|
+
return toKebab(key);
|
|
83
|
+
}
|
|
84
|
+
// ============================================================
|
|
85
|
+
// Dynamic Runtime CSS Injection Engine
|
|
86
|
+
// ============================================================
|
|
87
|
+
const injectedRuleSet = new Set();
|
|
88
|
+
const styleBuckets = {};
|
|
89
|
+
function getBucketElement(bucket) {
|
|
90
|
+
if (typeof document === 'undefined')
|
|
91
|
+
return null;
|
|
92
|
+
if (styleBuckets[bucket] && document.head.contains(styleBuckets[bucket])) {
|
|
93
|
+
return styleBuckets[bucket];
|
|
94
|
+
}
|
|
95
|
+
const safeId = `ttdk-dyn-${bucket.replace('_', '-')}`;
|
|
96
|
+
let el = document.getElementById(safeId);
|
|
97
|
+
if (!el) {
|
|
98
|
+
el = document.createElement('style');
|
|
99
|
+
el.id = safeId;
|
|
100
|
+
el.setAttribute('data-ttdk-dynamic', 'true');
|
|
101
|
+
// Pastikan urutan tag style di <head> sesuai cascade specificity
|
|
102
|
+
const bucketIndex = BUCKET_ORDER.indexOf(bucket);
|
|
103
|
+
let nextSibling = null;
|
|
104
|
+
if (bucketIndex !== -1) {
|
|
105
|
+
for (let i = bucketIndex + 1; i < BUCKET_ORDER.length; i++) {
|
|
106
|
+
const nextId = `ttdk-dyn-${BUCKET_ORDER[i].replace('_', '-')}`;
|
|
107
|
+
const nextEl = document.getElementById(nextId);
|
|
108
|
+
if (nextEl) {
|
|
109
|
+
nextSibling = nextEl;
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (nextSibling) {
|
|
115
|
+
document.head.insertBefore(el, nextSibling);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
document.head.appendChild(el);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
styleBuckets[bucket] = el;
|
|
122
|
+
return el;
|
|
123
|
+
}
|
|
124
|
+
export function injectDynamicCss(bucket, ruleKey, cssRule) {
|
|
125
|
+
if (injectedRuleSet.has(ruleKey))
|
|
126
|
+
return;
|
|
127
|
+
injectedRuleSet.add(ruleKey);
|
|
128
|
+
const el = getBucketElement(bucket);
|
|
129
|
+
if (!el)
|
|
130
|
+
return;
|
|
131
|
+
el.appendChild(document.createTextNode(cssRule + '\n'));
|
|
132
|
+
}
|
|
133
|
+
function getBaseVarRule(pseudo, varName, cssProp) {
|
|
134
|
+
const baseVar = varName.replace(`-${pseudo}-`, '-');
|
|
135
|
+
if (baseVar === varName)
|
|
136
|
+
return '';
|
|
137
|
+
let extra = `${baseVar}: var(${varName}) !important;`;
|
|
138
|
+
// Extra aliases for background
|
|
139
|
+
if (baseVar.endsWith('-background') || baseVar.endsWith('-bg')) {
|
|
140
|
+
extra += ` ${baseVar.replace(/-(background|bg)$/, '-bg')}: var(${varName}) !important;`;
|
|
141
|
+
extra += ` ${baseVar.replace(/-(background|bg)$/, '-background')}: var(${varName}) !important;`;
|
|
142
|
+
extra += ` ${baseVar.replace(/-(background|bg)$/, '-background-color')}: var(${varName}) !important;`;
|
|
143
|
+
}
|
|
144
|
+
return extra;
|
|
145
|
+
}
|
|
146
|
+
function injectPseudoRule(pseudo, varName, cssProp) {
|
|
147
|
+
const baseVarRule = getBaseVarRule(pseudo, varName, cssProp);
|
|
148
|
+
// Dark mode menggunakan ancestor class selector, bukan CSS pseudo-class
|
|
149
|
+
if (pseudo === 'dark') {
|
|
150
|
+
const selector = `.dark [style*="${varName}:"], .dark[style*="${varName}:"], [data-theme="dark"] [style*="${varName}:"], [data-theme="dark"][style*="${varName}:"]`;
|
|
151
|
+
const rule = `${selector} { ${cssProp}: var(${varName}) !important; ${baseVarRule} }`;
|
|
152
|
+
injectDynamicCss('pseudos', `pseudo:${varName}:${cssProp}`, rule);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
let pseudoSelector = `:hover`;
|
|
156
|
+
if (pseudo === 'active')
|
|
157
|
+
pseudoSelector = `:active`;
|
|
158
|
+
else if (pseudo === 'focus')
|
|
159
|
+
pseudoSelector = `:focus, [style*="${varName}:"]:focus-visible`;
|
|
160
|
+
else if (pseudo === 'disabled')
|
|
161
|
+
pseudoSelector = `:disabled, [style*="${varName}:"][aria-disabled="true"]`;
|
|
162
|
+
const rule = `[style*="${varName}:"]${pseudoSelector} { ${cssProp}: var(${varName}) !important; ${baseVarRule} }`;
|
|
163
|
+
injectDynamicCss('pseudos', `pseudo:${varName}:${cssProp}`, rule);
|
|
164
|
+
}
|
|
165
|
+
function injectBreakpointRule(bp, varName, cssProp) {
|
|
166
|
+
const query = BREAKPOINT_QUERIES[bp];
|
|
167
|
+
if (!query)
|
|
168
|
+
return;
|
|
169
|
+
const rule = `@media ${query} { [style*="${varName}:"] { ${cssProp}: var(${varName}) !important; } }`;
|
|
170
|
+
injectDynamicCss(bp, `bp:${bp}:${varName}:${cssProp}`, rule);
|
|
171
|
+
}
|
|
172
|
+
function injectNestedPseudoBreakpointRule(bp, pseudo, varName, cssProp) {
|
|
173
|
+
const query = BREAKPOINT_QUERIES[bp];
|
|
174
|
+
if (!query)
|
|
175
|
+
return;
|
|
176
|
+
const baseVarRule = getBaseVarRule(pseudo, varName, cssProp);
|
|
177
|
+
// Dark mode menggunakan ancestor class selector dalam media query
|
|
178
|
+
if (pseudo === 'dark') {
|
|
179
|
+
const selector = `.dark [style*="${varName}:"], .dark[style*="${varName}:"], [data-theme="dark"] [style*="${varName}:"], [data-theme="dark"][style*="${varName}:"]`;
|
|
180
|
+
const rule = `@media ${query} { ${selector} { ${cssProp}: var(${varName}) !important; ${baseVarRule} } }`;
|
|
181
|
+
injectDynamicCss(bp, `nested:${bp}:${pseudo}:${varName}:${cssProp}`, rule);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
let pseudoSelector = `:hover`;
|
|
185
|
+
if (pseudo === 'active')
|
|
186
|
+
pseudoSelector = `:active`;
|
|
187
|
+
else if (pseudo === 'focus')
|
|
188
|
+
pseudoSelector = `:focus, [style*="${varName}:"]:focus-visible`;
|
|
189
|
+
else if (pseudo === 'disabled')
|
|
190
|
+
pseudoSelector = `:disabled, [style*="${varName}:"][aria-disabled="true"]`;
|
|
191
|
+
const rule = `@media ${query} { [style*="${varName}:"]${pseudoSelector} { ${cssProp}: var(${varName}) !important; ${baseVarRule} } }`;
|
|
192
|
+
injectDynamicCss(bp, `nested:${bp}:${pseudo}:${varName}:${cssProp}`, rule);
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Mengambil properti CSS native biasa (seperti color, fontSize, letterSpacing, transform, dll.)
|
|
196
|
+
* untuk langsung diterapkan sebagai inline style native browser.
|
|
197
|
+
* Mengabaikan pseudo-classes ('hover', 'focus') dan responsive breakpoints ('sm', 'md', dll.).
|
|
198
|
+
*/
|
|
199
|
+
export function extractBaseStyles(ui) {
|
|
200
|
+
if (!ui || typeof ui !== 'object')
|
|
201
|
+
return {};
|
|
202
|
+
const base = {};
|
|
203
|
+
for (const [key, value] of Object.entries(ui)) {
|
|
204
|
+
if (value === undefined || value === null)
|
|
205
|
+
continue;
|
|
206
|
+
if (PSEUDOS.includes(key) || BREAKPOINTS.includes(key))
|
|
207
|
+
continue;
|
|
208
|
+
if (typeof value === 'object')
|
|
209
|
+
continue;
|
|
210
|
+
const cleaned = typeof value === 'string' ? cleanUiValue(value) : value;
|
|
211
|
+
// Support alias
|
|
212
|
+
if (key === 'bg') {
|
|
213
|
+
base['backgroundColor'] = cleaned;
|
|
214
|
+
}
|
|
215
|
+
else if (key === 'size') {
|
|
216
|
+
base['fontSize'] = cleaned;
|
|
217
|
+
}
|
|
218
|
+
else if (key === 'weight') {
|
|
219
|
+
base['fontWeight'] = cleaned;
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
base[key] = cleaned;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return base;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* buildUiVars — konversi UiProps ke CSS custom properties untuk dipakai di style attribute
|
|
229
|
+
* sekaligus mendaftarkan aturan dinamis (pseudo & responsive media queries) secara otomatis.
|
|
230
|
+
*/
|
|
231
|
+
export function buildUiVars(ui, prefix = '--ttdk-ui') {
|
|
232
|
+
if (!ui)
|
|
233
|
+
return {};
|
|
234
|
+
const vars = { ...extractBaseStyles(ui) };
|
|
235
|
+
// 1. Base props
|
|
236
|
+
for (const [key, value] of Object.entries(ui)) {
|
|
237
|
+
if (value === undefined || value === null)
|
|
238
|
+
continue;
|
|
239
|
+
if (PSEUDOS.includes(key) || BREAKPOINTS.includes(key))
|
|
240
|
+
continue;
|
|
241
|
+
if (typeof value === 'object')
|
|
242
|
+
continue;
|
|
243
|
+
const strVal = cleanUiValue(value);
|
|
244
|
+
vars[`${prefix}-${toKebab(key)}`] = strVal;
|
|
245
|
+
if (key === 'bg') {
|
|
246
|
+
vars[`${prefix}-background`] = strVal;
|
|
247
|
+
vars[`${prefix}-background-color`] = strVal;
|
|
248
|
+
}
|
|
249
|
+
else if (key === 'background' || key === 'backgroundColor') {
|
|
250
|
+
vars[`${prefix}-background`] = strVal;
|
|
251
|
+
vars[`${prefix}-bg`] = strVal;
|
|
252
|
+
}
|
|
253
|
+
else if (key === 'size') {
|
|
254
|
+
vars[`${prefix}-font-size`] = strVal;
|
|
255
|
+
}
|
|
256
|
+
else if (key === 'weight') {
|
|
257
|
+
vars[`${prefix}-font-weight`] = strVal;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
// 2. Pseudo-classes at root: hover: { color: 'red', md: { color: 'blue' } }
|
|
261
|
+
for (const pseudo of PSEUDOS) {
|
|
262
|
+
const pseudoObj = ui[pseudo];
|
|
263
|
+
if (!pseudoObj || typeof pseudoObj !== 'object')
|
|
264
|
+
continue;
|
|
265
|
+
for (const [key, value] of Object.entries(pseudoObj)) {
|
|
266
|
+
if (value === undefined || value === null)
|
|
267
|
+
continue;
|
|
268
|
+
// Nested breakpoint inside pseudo: hover: { md: { background: 'blue' } }
|
|
269
|
+
if (BREAKPOINTS.includes(key)) {
|
|
270
|
+
const bpObj = value;
|
|
271
|
+
if (bpObj && typeof bpObj === 'object') {
|
|
272
|
+
for (const [subKey, subVal] of Object.entries(bpObj)) {
|
|
273
|
+
if (subVal === undefined || subVal === null || typeof subVal === 'object')
|
|
274
|
+
continue;
|
|
275
|
+
const kebab = toKebab(subKey);
|
|
276
|
+
const varName = `${prefix}-${pseudo}-${kebab}-${key}`;
|
|
277
|
+
vars[varName] = String(subVal);
|
|
278
|
+
injectNestedPseudoBreakpointRule(key, pseudo, varName, resolveCssProperty(subKey));
|
|
279
|
+
if (subKey === 'bg') {
|
|
280
|
+
const bgVar = `${prefix}-${pseudo}-background-${key}`;
|
|
281
|
+
vars[bgVar] = String(subVal);
|
|
282
|
+
injectNestedPseudoBreakpointRule(key, pseudo, bgVar, 'background');
|
|
283
|
+
const bgColVar = `${prefix}-${pseudo}-background-color-${key}`;
|
|
284
|
+
vars[bgColVar] = String(subVal);
|
|
285
|
+
injectNestedPseudoBreakpointRule(key, pseudo, bgColVar, 'background-color');
|
|
286
|
+
}
|
|
287
|
+
else if (subKey === 'background' || subKey === 'backgroundColor') {
|
|
288
|
+
const bgVar = `${prefix}-${pseudo}-background-${key}`;
|
|
289
|
+
vars[bgVar] = String(subVal);
|
|
290
|
+
injectNestedPseudoBreakpointRule(key, pseudo, bgVar, 'background');
|
|
291
|
+
const bgShortVar = `${prefix}-${pseudo}-bg-${key}`;
|
|
292
|
+
vars[bgShortVar] = String(subVal);
|
|
293
|
+
injectNestedPseudoBreakpointRule(key, pseudo, bgShortVar, 'background');
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
if (typeof value === 'object')
|
|
300
|
+
continue;
|
|
301
|
+
const kebab = toKebab(key);
|
|
302
|
+
const varName = `${prefix}-${pseudo}-${kebab}`;
|
|
303
|
+
vars[varName] = String(value);
|
|
304
|
+
injectPseudoRule(pseudo, varName, resolveCssProperty(key));
|
|
305
|
+
// alias: backgroundColor / bg
|
|
306
|
+
if (key === 'backgroundColor' || key === 'bg') {
|
|
307
|
+
const bgVar = `${prefix}-${pseudo}-background`;
|
|
308
|
+
vars[bgVar] = String(value);
|
|
309
|
+
injectPseudoRule(pseudo, bgVar, 'background');
|
|
310
|
+
const bgShortVar = `${prefix}-${pseudo}-bg`;
|
|
311
|
+
vars[bgShortVar] = String(value);
|
|
312
|
+
injectPseudoRule(pseudo, bgShortVar, 'background');
|
|
313
|
+
}
|
|
314
|
+
else if (key === 'background') {
|
|
315
|
+
const bgShortVar = `${prefix}-${pseudo}-bg`;
|
|
316
|
+
vars[bgShortVar] = String(value);
|
|
317
|
+
injectPseudoRule(pseudo, bgShortVar, 'background');
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
// 3. Breakpoints at root: md: { background: 'teal', hover: { background: '#fae8ff' } }
|
|
322
|
+
for (const bp of BREAKPOINTS) {
|
|
323
|
+
const bpObj = ui[bp];
|
|
324
|
+
if (!bpObj || typeof bpObj !== 'object')
|
|
325
|
+
continue;
|
|
326
|
+
for (const [key, value] of Object.entries(bpObj)) {
|
|
327
|
+
if (value === undefined || value === null)
|
|
328
|
+
continue;
|
|
329
|
+
// Nested pseudo inside breakpoint: md: { hover: { background: '#fae8ff' } }
|
|
330
|
+
if (PSEUDOS.includes(key)) {
|
|
331
|
+
const pseudoObj = value;
|
|
332
|
+
if (pseudoObj && typeof pseudoObj === 'object') {
|
|
333
|
+
for (const [pseudoKey, pseudoVal] of Object.entries(pseudoObj)) {
|
|
334
|
+
if (pseudoVal === undefined || pseudoVal === null || typeof pseudoVal === 'object')
|
|
335
|
+
continue;
|
|
336
|
+
const kebab = toKebab(pseudoKey);
|
|
337
|
+
const varName = `${prefix}-${key}-${kebab}-${bp}`;
|
|
338
|
+
vars[varName] = String(pseudoVal);
|
|
339
|
+
injectNestedPseudoBreakpointRule(bp, key, varName, resolveCssProperty(pseudoKey));
|
|
340
|
+
if (pseudoKey === 'bg') {
|
|
341
|
+
const bgVar = `${prefix}-${key}-background-${bp}`;
|
|
342
|
+
vars[bgVar] = String(pseudoVal);
|
|
343
|
+
injectNestedPseudoBreakpointRule(bp, key, bgVar, 'background');
|
|
344
|
+
const bgColVar = `${prefix}-${key}-background-color-${bp}`;
|
|
345
|
+
vars[bgColVar] = String(pseudoVal);
|
|
346
|
+
injectNestedPseudoBreakpointRule(bp, key, bgColVar, 'background-color');
|
|
347
|
+
}
|
|
348
|
+
else if (pseudoKey === 'background' || pseudoKey === 'backgroundColor') {
|
|
349
|
+
const bgVar = `${prefix}-${key}-background-${bp}`;
|
|
350
|
+
vars[bgVar] = String(pseudoVal);
|
|
351
|
+
injectNestedPseudoBreakpointRule(bp, key, bgVar, 'background');
|
|
352
|
+
const bgShortVar = `${prefix}-${key}-bg-${bp}`;
|
|
353
|
+
vars[bgShortVar] = String(pseudoVal);
|
|
354
|
+
injectNestedPseudoBreakpointRule(bp, key, bgShortVar, 'background');
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
continue;
|
|
359
|
+
}
|
|
360
|
+
if (typeof value === 'object')
|
|
361
|
+
continue;
|
|
362
|
+
const kebab = toKebab(key);
|
|
363
|
+
const varName = `${prefix}-${kebab}-${bp}`;
|
|
364
|
+
vars[varName] = String(value);
|
|
365
|
+
injectBreakpointRule(bp, varName, resolveCssProperty(key));
|
|
366
|
+
if (key === 'bg') {
|
|
367
|
+
const bgVar = `${prefix}-background-${bp}`;
|
|
368
|
+
vars[bgVar] = String(value);
|
|
369
|
+
injectBreakpointRule(bp, bgVar, 'background');
|
|
370
|
+
const bgColVar = `${prefix}-background-color-${bp}`;
|
|
371
|
+
vars[bgColVar] = String(value);
|
|
372
|
+
injectBreakpointRule(bp, bgColVar, 'background-color');
|
|
373
|
+
}
|
|
374
|
+
else if (key === 'background' || key === 'backgroundColor') {
|
|
375
|
+
const bgVar = `${prefix}-background-${bp}`;
|
|
376
|
+
vars[bgVar] = String(value);
|
|
377
|
+
injectBreakpointRule(bp, bgVar, 'background');
|
|
378
|
+
const bgShortVar = `${prefix}-bg-${bp}`;
|
|
379
|
+
vars[bgShortVar] = String(value);
|
|
380
|
+
injectBreakpointRule(bp, bgShortVar, 'background');
|
|
381
|
+
}
|
|
382
|
+
else if (key === 'size') {
|
|
383
|
+
const sizeVar = `${prefix}-font-size-${bp}`;
|
|
384
|
+
vars[sizeVar] = String(value);
|
|
385
|
+
injectBreakpointRule(bp, sizeVar, 'font-size');
|
|
386
|
+
}
|
|
387
|
+
else if (key === 'weight') {
|
|
388
|
+
const weightVar = `${prefix}-font-weight-${bp}`;
|
|
389
|
+
vars[weightVar] = String(value);
|
|
390
|
+
injectBreakpointRule(bp, weightVar, 'font-weight');
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
return vars;
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* buildUiStyle — Solusi HYBRID:
|
|
398
|
+
* Menggabungkan native inline style (agar ratusan CSS properties native langsung jalan 100%)
|
|
399
|
+
* dengan CSS custom properties (agar :hover dan responsive media query tetap bekerja sempurna).
|
|
400
|
+
*/
|
|
401
|
+
export function buildUiStyle(ui, prefix = '--ttdk-ui') {
|
|
402
|
+
return buildUiVars(ui, prefix);
|
|
403
|
+
}
|
|
404
|
+
// ============================================================
|
|
405
|
+
// Layout Helpers for Flex & Grid
|
|
406
|
+
// ============================================================
|
|
407
|
+
function mapFlexJustify(val) {
|
|
408
|
+
if (!val)
|
|
409
|
+
return undefined;
|
|
410
|
+
if (val === 'start')
|
|
411
|
+
return 'flex-start';
|
|
412
|
+
if (val === 'end')
|
|
413
|
+
return 'flex-end';
|
|
414
|
+
if (val === 'around')
|
|
415
|
+
return 'space-around';
|
|
416
|
+
if (val === 'between')
|
|
417
|
+
return 'space-between';
|
|
418
|
+
if (val === 'evenly')
|
|
419
|
+
return 'space-evenly';
|
|
420
|
+
return val;
|
|
421
|
+
}
|
|
422
|
+
function mapFlexAlign(val) {
|
|
423
|
+
if (!val)
|
|
424
|
+
return undefined;
|
|
425
|
+
if (val === 'start')
|
|
426
|
+
return 'flex-start';
|
|
427
|
+
if (val === 'end')
|
|
428
|
+
return 'flex-end';
|
|
429
|
+
return val;
|
|
430
|
+
}
|
|
431
|
+
function formatGap(val) {
|
|
432
|
+
if (val === undefined || val === null || val === '')
|
|
433
|
+
return undefined;
|
|
434
|
+
if (typeof val === 'number')
|
|
435
|
+
return `${val}px`;
|
|
436
|
+
return String(val);
|
|
437
|
+
}
|
|
438
|
+
export function buildFlexVars(props) {
|
|
439
|
+
if (!props)
|
|
440
|
+
return {};
|
|
441
|
+
const vars = {};
|
|
442
|
+
// Base
|
|
443
|
+
if (props.direction)
|
|
444
|
+
vars['--ttdk-flex-direction'] = props.direction;
|
|
445
|
+
if (props.justifyContent)
|
|
446
|
+
vars['--ttdk-flex-justify-content'] = mapFlexJustify(props.justifyContent) || props.justifyContent;
|
|
447
|
+
if (props.alignItems)
|
|
448
|
+
vars['--ttdk-flex-align-items'] = mapFlexAlign(props.alignItems) || props.alignItems;
|
|
449
|
+
if (props.gap !== undefined) {
|
|
450
|
+
const g = formatGap(props.gap);
|
|
451
|
+
if (g)
|
|
452
|
+
vars['--ttdk-flex-gap'] = g;
|
|
453
|
+
}
|
|
454
|
+
if (props.wrap)
|
|
455
|
+
vars['--ttdk-flex-wrap'] = props.wrap;
|
|
456
|
+
// Breakpoints
|
|
457
|
+
const bps = ['sm', 'md', 'lg', 'xl', '2xl'];
|
|
458
|
+
for (const bp of bps) {
|
|
459
|
+
const override = props[bp] || (bp === '2xl' ? (props['xxl'] || props['2xl']) : undefined);
|
|
460
|
+
if (override && typeof override === 'object') {
|
|
461
|
+
if (override.direction)
|
|
462
|
+
vars[`--ttdk-flex-direction-${bp}`] = override.direction;
|
|
463
|
+
if (override.justifyContent)
|
|
464
|
+
vars[`--ttdk-flex-justify-content-${bp}`] = mapFlexJustify(override.justifyContent) || override.justifyContent;
|
|
465
|
+
if (override.alignItems)
|
|
466
|
+
vars[`--ttdk-flex-align-items-${bp}`] = mapFlexAlign(override.alignItems) || override.alignItems;
|
|
467
|
+
if (override.gap !== undefined) {
|
|
468
|
+
const g = formatGap(override.gap);
|
|
469
|
+
if (g)
|
|
470
|
+
vars[`--ttdk-flex-gap-${bp}`] = g;
|
|
471
|
+
}
|
|
472
|
+
if (override.wrap)
|
|
473
|
+
vars[`--ttdk-flex-wrap-${bp}`] = override.wrap;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
return vars;
|
|
477
|
+
}
|
|
478
|
+
function mapFlexAlignSelf(val) {
|
|
479
|
+
if (!val)
|
|
480
|
+
return undefined;
|
|
481
|
+
if (val === 'start')
|
|
482
|
+
return 'flex-start';
|
|
483
|
+
if (val === 'end')
|
|
484
|
+
return 'flex-end';
|
|
485
|
+
return val;
|
|
486
|
+
}
|
|
487
|
+
function formatFlexBasis(val) {
|
|
488
|
+
if (val === undefined || val === null || val === '')
|
|
489
|
+
return undefined;
|
|
490
|
+
if (typeof val === 'number')
|
|
491
|
+
return `${val}px`;
|
|
492
|
+
return String(val);
|
|
493
|
+
}
|
|
494
|
+
function formatFlexGrowShrink(val) {
|
|
495
|
+
if (val === undefined || val === null)
|
|
496
|
+
return undefined;
|
|
497
|
+
if (typeof val === 'boolean')
|
|
498
|
+
return val ? '1' : '0';
|
|
499
|
+
return String(val);
|
|
500
|
+
}
|
|
501
|
+
export function buildFlexItemVars(props) {
|
|
502
|
+
if (!props)
|
|
503
|
+
return {};
|
|
504
|
+
const vars = {};
|
|
505
|
+
// Base
|
|
506
|
+
if (props.order !== undefined)
|
|
507
|
+
vars['--ttdk-flex-item-order'] = String(props.order);
|
|
508
|
+
if (props.grow !== undefined) {
|
|
509
|
+
const g = formatFlexGrowShrink(props.grow);
|
|
510
|
+
if (g)
|
|
511
|
+
vars['--ttdk-flex-item-grow'] = g;
|
|
512
|
+
}
|
|
513
|
+
if (props.shrink !== undefined) {
|
|
514
|
+
const s = formatFlexGrowShrink(props.shrink);
|
|
515
|
+
if (s)
|
|
516
|
+
vars['--ttdk-flex-item-shrink'] = s;
|
|
517
|
+
}
|
|
518
|
+
if (props.basis !== undefined) {
|
|
519
|
+
const b = formatFlexBasis(props.basis);
|
|
520
|
+
if (b)
|
|
521
|
+
vars['--ttdk-flex-item-basis'] = b;
|
|
522
|
+
}
|
|
523
|
+
if (props.alignSelf)
|
|
524
|
+
vars['--ttdk-flex-item-align-self'] = mapFlexAlignSelf(props.alignSelf) || props.alignSelf;
|
|
525
|
+
// Breakpoints
|
|
526
|
+
const bps = ['sm', 'md', 'lg', 'xl', '2xl'];
|
|
527
|
+
for (const bp of bps) {
|
|
528
|
+
const override = props[bp] || (bp === '2xl' ? (props['xxl'] || props['2xl']) : undefined);
|
|
529
|
+
if (override && typeof override === 'object') {
|
|
530
|
+
if (override.order !== undefined)
|
|
531
|
+
vars[`--ttdk-flex-item-order-${bp}`] = String(override.order);
|
|
532
|
+
if (override.grow !== undefined) {
|
|
533
|
+
const g = formatFlexGrowShrink(override.grow);
|
|
534
|
+
if (g)
|
|
535
|
+
vars[`--ttdk-flex-item-grow-${bp}`] = g;
|
|
536
|
+
}
|
|
537
|
+
if (override.shrink !== undefined) {
|
|
538
|
+
const s = formatFlexGrowShrink(override.shrink);
|
|
539
|
+
if (s)
|
|
540
|
+
vars[`--ttdk-flex-item-shrink-${bp}`] = s;
|
|
541
|
+
}
|
|
542
|
+
if (override.basis !== undefined) {
|
|
543
|
+
const b = formatFlexBasis(override.basis);
|
|
544
|
+
if (b)
|
|
545
|
+
vars[`--ttdk-flex-item-basis-${bp}`] = b;
|
|
546
|
+
}
|
|
547
|
+
if (override.alignSelf)
|
|
548
|
+
vars[`--ttdk-flex-item-align-self-${bp}`] = mapFlexAlignSelf(override.alignSelf) || override.alignSelf;
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
return vars;
|
|
552
|
+
}
|
|
553
|
+
function formatGridTemplate(val) {
|
|
554
|
+
if (val === undefined || val === null || val === '')
|
|
555
|
+
return undefined;
|
|
556
|
+
if (typeof val === 'number')
|
|
557
|
+
return `repeat(${val}, minmax(0, 1fr))`;
|
|
558
|
+
return String(val);
|
|
559
|
+
}
|
|
560
|
+
function mapGridJustifyContent(val) {
|
|
561
|
+
if (!val)
|
|
562
|
+
return undefined;
|
|
563
|
+
if (val === 'start')
|
|
564
|
+
return 'start';
|
|
565
|
+
if (val === 'center')
|
|
566
|
+
return 'center';
|
|
567
|
+
if (val === 'end')
|
|
568
|
+
return 'end';
|
|
569
|
+
if (val === 'around')
|
|
570
|
+
return 'space-around';
|
|
571
|
+
if (val === 'between')
|
|
572
|
+
return 'space-between';
|
|
573
|
+
if (val === 'evenly')
|
|
574
|
+
return 'space-evenly';
|
|
575
|
+
return val;
|
|
576
|
+
}
|
|
577
|
+
function mapGridAlignContent(val) {
|
|
578
|
+
if (!val)
|
|
579
|
+
return undefined;
|
|
580
|
+
if (val === 'start')
|
|
581
|
+
return 'start';
|
|
582
|
+
if (val === 'center')
|
|
583
|
+
return 'center';
|
|
584
|
+
if (val === 'end')
|
|
585
|
+
return 'end';
|
|
586
|
+
if (val === 'around')
|
|
587
|
+
return 'space-around';
|
|
588
|
+
if (val === 'between')
|
|
589
|
+
return 'space-between';
|
|
590
|
+
if (val === 'evenly')
|
|
591
|
+
return 'space-evenly';
|
|
592
|
+
return val;
|
|
593
|
+
}
|
|
594
|
+
export function buildGridVars(props) {
|
|
595
|
+
if (!props)
|
|
596
|
+
return {};
|
|
597
|
+
const vars = {};
|
|
598
|
+
// Base
|
|
599
|
+
if (props.templateColumns !== undefined) {
|
|
600
|
+
const tc = formatGridTemplate(props.templateColumns);
|
|
601
|
+
if (tc)
|
|
602
|
+
vars['--ttdk-grid-template-columns'] = tc;
|
|
603
|
+
}
|
|
604
|
+
if (props.templateRows !== undefined) {
|
|
605
|
+
const tr = formatGridTemplate(props.templateRows);
|
|
606
|
+
if (tr)
|
|
607
|
+
vars['--ttdk-grid-template-rows'] = tr;
|
|
608
|
+
}
|
|
609
|
+
if (props.gap !== undefined) {
|
|
610
|
+
const g = formatGap(props.gap);
|
|
611
|
+
if (g)
|
|
612
|
+
vars['--ttdk-grid-gap'] = g;
|
|
613
|
+
}
|
|
614
|
+
if (props.justifyContent) {
|
|
615
|
+
vars['--ttdk-grid-justify-content'] = mapGridJustifyContent(props.justifyContent) || props.justifyContent;
|
|
616
|
+
}
|
|
617
|
+
if (props.alignContent) {
|
|
618
|
+
vars['--ttdk-grid-align-content'] = mapGridAlignContent(props.alignContent) || props.alignContent;
|
|
619
|
+
}
|
|
620
|
+
// Breakpoints
|
|
621
|
+
const bps = ['sm', 'md', 'lg', 'xl', '2xl'];
|
|
622
|
+
for (const bp of bps) {
|
|
623
|
+
const override = props[bp] || (bp === '2xl' ? (props['xxl'] || props['2xl']) : undefined);
|
|
624
|
+
if (override && typeof override === 'object') {
|
|
625
|
+
if (override.templateColumns !== undefined) {
|
|
626
|
+
const tc = formatGridTemplate(override.templateColumns);
|
|
627
|
+
if (tc)
|
|
628
|
+
vars[`--ttdk-grid-template-columns-${bp}`] = tc;
|
|
629
|
+
}
|
|
630
|
+
if (override.templateRows !== undefined) {
|
|
631
|
+
const tr = formatGridTemplate(override.templateRows);
|
|
632
|
+
if (tr)
|
|
633
|
+
vars[`--ttdk-grid-template-rows-${bp}`] = tr;
|
|
634
|
+
}
|
|
635
|
+
if (override.gap !== undefined) {
|
|
636
|
+
const g = formatGap(override.gap);
|
|
637
|
+
if (g)
|
|
638
|
+
vars[`--ttdk-grid-gap-${bp}`] = g;
|
|
639
|
+
}
|
|
640
|
+
if (override.justifyContent) {
|
|
641
|
+
vars[`--ttdk-grid-justify-content-${bp}`] = mapGridJustifyContent(override.justifyContent) || override.justifyContent;
|
|
642
|
+
}
|
|
643
|
+
if (override.alignContent) {
|
|
644
|
+
vars[`--ttdk-grid-align-content-${bp}`] = mapGridAlignContent(override.alignContent) || override.alignContent;
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
return vars;
|
|
649
|
+
}
|
|
650
|
+
function formatGridColRow(val) {
|
|
651
|
+
if (val === undefined || val === null || val === '')
|
|
652
|
+
return undefined;
|
|
653
|
+
if (typeof val === 'number')
|
|
654
|
+
return `span ${val} / span ${val}`;
|
|
655
|
+
if (val === 'auto')
|
|
656
|
+
return 'auto';
|
|
657
|
+
if (val === 'full')
|
|
658
|
+
return '1 / -1';
|
|
659
|
+
return String(val);
|
|
660
|
+
}
|
|
661
|
+
function resolveGridTrack(span, start, end) {
|
|
662
|
+
const hasSpan = span !== undefined && span !== null && span !== '';
|
|
663
|
+
const hasStart = start !== undefined && start !== null && start !== '';
|
|
664
|
+
const hasEnd = end !== undefined && end !== null && end !== '';
|
|
665
|
+
if (!hasSpan && !hasStart && !hasEnd)
|
|
666
|
+
return undefined;
|
|
667
|
+
if (hasStart && hasEnd) {
|
|
668
|
+
return `${start} / ${end}`;
|
|
669
|
+
}
|
|
670
|
+
if (hasStart && hasSpan) {
|
|
671
|
+
const spanStr = typeof span === 'number' ? `span ${span}` : String(span);
|
|
672
|
+
return `${start} / ${spanStr}`;
|
|
673
|
+
}
|
|
674
|
+
if (hasEnd && hasSpan) {
|
|
675
|
+
const spanStr = typeof span === 'number' ? `span ${span}` : String(span);
|
|
676
|
+
return `${spanStr} / ${end}`;
|
|
677
|
+
}
|
|
678
|
+
if (hasStart) {
|
|
679
|
+
return `${start} / auto`;
|
|
680
|
+
}
|
|
681
|
+
if (hasEnd) {
|
|
682
|
+
return `auto / ${end}`;
|
|
683
|
+
}
|
|
684
|
+
return formatGridColRow(span);
|
|
685
|
+
}
|
|
686
|
+
export function buildGridItemVars(props) {
|
|
687
|
+
if (!props)
|
|
688
|
+
return {};
|
|
689
|
+
const vars = {};
|
|
690
|
+
// Base
|
|
691
|
+
const colVal = resolveGridTrack(props.col, props.colStart, props.colEnd);
|
|
692
|
+
if (colVal)
|
|
693
|
+
vars['--ttdk-grid-item-col'] = colVal;
|
|
694
|
+
if (props.colStart !== undefined)
|
|
695
|
+
vars['--ttdk-grid-item-col-start'] = String(props.colStart);
|
|
696
|
+
if (props.colEnd !== undefined)
|
|
697
|
+
vars['--ttdk-grid-item-col-end'] = String(props.colEnd);
|
|
698
|
+
const rowVal = resolveGridTrack(props.row, props.rowStart, props.rowEnd);
|
|
699
|
+
if (rowVal)
|
|
700
|
+
vars['--ttdk-grid-item-row'] = rowVal;
|
|
701
|
+
if (props.rowStart !== undefined)
|
|
702
|
+
vars['--ttdk-grid-item-row-start'] = String(props.rowStart);
|
|
703
|
+
if (props.rowEnd !== undefined)
|
|
704
|
+
vars['--ttdk-grid-item-row-end'] = String(props.rowEnd);
|
|
705
|
+
if (props.justifySelf)
|
|
706
|
+
vars['--ttdk-grid-item-justify-self'] = props.justifySelf;
|
|
707
|
+
if (props.order !== undefined)
|
|
708
|
+
vars['--ttdk-grid-item-order'] = String(props.order);
|
|
709
|
+
// Breakpoints
|
|
710
|
+
const bps = ['sm', 'md', 'lg', 'xl', '2xl'];
|
|
711
|
+
for (const bp of bps) {
|
|
712
|
+
const override = props[bp] || (bp === '2xl' ? (props['xxl'] || props['2xl']) : undefined);
|
|
713
|
+
if (override && typeof override === 'object') {
|
|
714
|
+
const bpColVal = resolveGridTrack(override.col, override.colStart, override.colEnd);
|
|
715
|
+
if (bpColVal)
|
|
716
|
+
vars[`--ttdk-grid-item-col-${bp}`] = bpColVal;
|
|
717
|
+
if (override.colStart !== undefined)
|
|
718
|
+
vars[`--ttdk-grid-item-col-start-${bp}`] = String(override.colStart);
|
|
719
|
+
if (override.colEnd !== undefined)
|
|
720
|
+
vars[`--ttdk-grid-item-col-end-${bp}`] = String(override.colEnd);
|
|
721
|
+
const bpRowVal = resolveGridTrack(override.row, override.rowStart, override.rowEnd);
|
|
722
|
+
if (bpRowVal)
|
|
723
|
+
vars[`--ttdk-grid-item-row-${bp}`] = bpRowVal;
|
|
724
|
+
if (override.rowStart !== undefined)
|
|
725
|
+
vars[`--ttdk-grid-item-row-start-${bp}`] = String(override.rowStart);
|
|
726
|
+
if (override.rowEnd !== undefined)
|
|
727
|
+
vars[`--ttdk-grid-item-row-end-${bp}`] = String(override.rowEnd);
|
|
728
|
+
if (override.justifySelf)
|
|
729
|
+
vars[`--ttdk-grid-item-justify-self-${bp}`] = override.justifySelf;
|
|
730
|
+
if (override.order !== undefined)
|
|
731
|
+
vars[`--ttdk-grid-item-order-${bp}`] = String(override.order);
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
return vars;
|
|
735
|
+
}
|