@ttdk-design-system/library-react 0.0.0-stage → 1.0.1

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.
Files changed (184) hide show
  1. package/AI_GUIDE.md +6518 -0
  2. package/README.md +106 -2
  3. package/llms.txt +6518 -0
  4. package/package.json +1099 -4
  5. package/src/core/index.ts +2 -0
  6. package/src/core/tailwind-preset.cjs +62 -0
  7. package/src/core/tailwind-preset.ts +85 -0
  8. package/src/core/theme/tokens.css +663 -0
  9. package/src/core/types.ts +836 -0
  10. package/src/index.ts +17 -0
  11. package/src/tailwind-preset.cjs +62 -0
  12. package/src/tailwind-preset.ts +85 -0
  13. package/src/types.ts +1 -0
  14. package/src/web/accordion/AI_GUIDE.md +149 -0
  15. package/src/web/accordion/accordion.css +1 -0
  16. package/src/web/accordion/accordion.tsx +430 -0
  17. package/src/web/accordion/index.ts +3 -0
  18. package/src/web/accordion/manifest.json +351 -0
  19. package/src/web/alert/AI_GUIDE.md +139 -0
  20. package/src/web/alert/alert.css +1 -0
  21. package/src/web/alert/alert.tsx +318 -0
  22. package/src/web/alert/index.ts +3 -0
  23. package/src/web/alert/manifest.json +240 -0
  24. package/src/web/avatar/AI_GUIDE.md +118 -0
  25. package/src/web/avatar/avatar.css +1 -0
  26. package/src/web/avatar/avatar.tsx +233 -0
  27. package/src/web/avatar/index.ts +3 -0
  28. package/src/web/avatar/manifest.json +195 -0
  29. package/src/web/badge/AI_GUIDE.md +94 -0
  30. package/src/web/badge/badge.css +1 -0
  31. package/src/web/badge/badge.tsx +140 -0
  32. package/src/web/badge/index.ts +2 -0
  33. package/src/web/badge/manifest.json +141 -0
  34. package/src/web/banner/AI_GUIDE.md +130 -0
  35. package/src/web/banner/banner.css +1 -0
  36. package/src/web/banner/banner.tsx +334 -0
  37. package/src/web/banner/index.ts +3 -0
  38. package/src/web/banner/manifest.json +240 -0
  39. package/src/web/breadcrumb/AI_GUIDE.md +120 -0
  40. package/src/web/breadcrumb/breadcrumb.css +1 -0
  41. package/src/web/breadcrumb/breadcrumb.tsx +306 -0
  42. package/src/web/breadcrumb/index.ts +3 -0
  43. package/src/web/breadcrumb/manifest.json +225 -0
  44. package/src/web/button/AI_GUIDE.md +121 -0
  45. package/src/web/button/button.css +1 -0
  46. package/src/web/button/button.tsx +287 -0
  47. package/src/web/button/index.ts +2 -0
  48. package/src/web/button/manifest.json +177 -0
  49. package/src/web/calendar/AI_GUIDE.md +151 -0
  50. package/src/web/calendar/calendar.css +1 -0
  51. package/src/web/calendar/calendar.tsx +1611 -0
  52. package/src/web/calendar/index.ts +3 -0
  53. package/src/web/calendar/manifest.json +470 -0
  54. package/src/web/card/AI_GUIDE.md +133 -0
  55. package/src/web/card/card.css +1 -0
  56. package/src/web/card/card.tsx +408 -0
  57. package/src/web/card/index.ts +4 -0
  58. package/src/web/card/manifest.json +357 -0
  59. package/src/web/checkbox/AI_GUIDE.md +146 -0
  60. package/src/web/checkbox/checkbox.css +1 -0
  61. package/src/web/checkbox/checkbox.tsx +307 -0
  62. package/src/web/checkbox/index.ts +2 -0
  63. package/src/web/checkbox/manifest.json +294 -0
  64. package/src/web/chip/AI_GUIDE.md +186 -0
  65. package/src/web/chip/chip.css +1 -0
  66. package/src/web/chip/chip.tsx +230 -0
  67. package/src/web/chip/index.ts +2 -0
  68. package/src/web/chip/manifest.json +186 -0
  69. package/src/web/dropdown/AI_GUIDE.md +167 -0
  70. package/src/web/dropdown/dropdown.css +1 -0
  71. package/src/web/dropdown/dropdown.tsx +1274 -0
  72. package/src/web/dropdown/index.ts +3 -0
  73. package/src/web/dropdown/manifest.json +576 -0
  74. package/src/web/flex/AI_GUIDE.md +113 -0
  75. package/src/web/flex/flex-item.tsx +97 -0
  76. package/src/web/flex/flex.css +1 -0
  77. package/src/web/flex/flex.tsx +108 -0
  78. package/src/web/flex/index.ts +5 -0
  79. package/src/web/flex/manifest.json +162 -0
  80. package/src/web/form/index.ts +7 -0
  81. package/src/web/grid/AI_GUIDE.md +112 -0
  82. package/src/web/grid/grid-item.tsx +112 -0
  83. package/src/web/grid/grid.css +1 -0
  84. package/src/web/grid/grid.tsx +99 -0
  85. package/src/web/grid/index.ts +5 -0
  86. package/src/web/grid/manifest.json +153 -0
  87. package/src/web/index.ts +86 -0
  88. package/src/web/input/AI_GUIDE.md +159 -0
  89. package/src/web/input/index.ts +3 -0
  90. package/src/web/input/input.css +1 -0
  91. package/src/web/input/input.tsx +537 -0
  92. package/src/web/input/manifest.json +465 -0
  93. package/src/web/input-number/AI_GUIDE.md +164 -0
  94. package/src/web/input-number/index.ts +3 -0
  95. package/src/web/input-number/input-number.css +1 -0
  96. package/src/web/input-number/input-number.tsx +1193 -0
  97. package/src/web/input-number/manifest.json +575 -0
  98. package/src/web/modal/AI_GUIDE.md +171 -0
  99. package/src/web/modal/index.ts +3 -0
  100. package/src/web/modal/manifest.json +375 -0
  101. package/src/web/modal/modal.css +1 -0
  102. package/src/web/modal/modal.tsx +571 -0
  103. package/src/web/pagination/AI_GUIDE.md +148 -0
  104. package/src/web/pagination/index.ts +21 -0
  105. package/src/web/pagination/manifest.json +432 -0
  106. package/src/web/pagination/pagination-content.tsx +45 -0
  107. package/src/web/pagination/pagination-ellipsis.tsx +54 -0
  108. package/src/web/pagination/pagination-first.tsx +155 -0
  109. package/src/web/pagination/pagination-item.tsx +45 -0
  110. package/src/web/pagination/pagination-last.tsx +155 -0
  111. package/src/web/pagination/pagination-link.tsx +121 -0
  112. package/src/web/pagination/pagination-next.tsx +158 -0
  113. package/src/web/pagination/pagination-previous.tsx +158 -0
  114. package/src/web/pagination/pagination.css +1 -0
  115. package/src/web/pagination/pagination.tsx +687 -0
  116. package/src/web/popover/AI_GUIDE.md +163 -0
  117. package/src/web/popover/index.ts +3 -0
  118. package/src/web/popover/manifest.json +396 -0
  119. package/src/web/popover/popover.css +1 -0
  120. package/src/web/popover/popover.tsx +702 -0
  121. package/src/web/radio/AI_GUIDE.md +155 -0
  122. package/src/web/radio/index.ts +2 -0
  123. package/src/web/radio/manifest.json +294 -0
  124. package/src/web/radio/radio.css +1 -0
  125. package/src/web/radio/radio.tsx +290 -0
  126. package/src/web/selectbox/AI_GUIDE.md +216 -0
  127. package/src/web/selectbox/index.ts +3 -0
  128. package/src/web/selectbox/manifest.json +477 -0
  129. package/src/web/selectbox/selectbox.css +1 -0
  130. package/src/web/selectbox/selectbox.tsx +1048 -0
  131. package/src/web/sonner/AI_GUIDE.md +98 -0
  132. package/src/web/sonner/index.ts +114 -0
  133. package/src/web/sonner/manifest.json +132 -0
  134. package/src/web/sonner/sonner.css +1 -0
  135. package/src/web/sonner/sonner.tsx +177 -0
  136. package/src/web/table/AI_GUIDE.md +145 -0
  137. package/src/web/table/index.ts +35 -0
  138. package/src/web/table/manifest.json +168 -0
  139. package/src/web/table/table-body.tsx +45 -0
  140. package/src/web/table/table-caption.tsx +45 -0
  141. package/src/web/table/table-cell.tsx +74 -0
  142. package/src/web/table/table-empty.tsx +108 -0
  143. package/src/web/table/table-footer.tsx +45 -0
  144. package/src/web/table/table-head.tsx +80 -0
  145. package/src/web/table/table-header.tsx +45 -0
  146. package/src/web/table/table-row.tsx +69 -0
  147. package/src/web/table/table.css +1 -0
  148. package/src/web/table/table.tsx +305 -0
  149. package/src/web/tabs/AI_GUIDE.md +150 -0
  150. package/src/web/tabs/index.ts +3 -0
  151. package/src/web/tabs/manifest.json +315 -0
  152. package/src/web/tabs/tabs.css +1 -0
  153. package/src/web/tabs/tabs.tsx +332 -0
  154. package/src/web/text/AI_GUIDE.md +129 -0
  155. package/src/web/text/index.ts +3 -0
  156. package/src/web/text/manifest.json +195 -0
  157. package/src/web/text/text.css +1 -0
  158. package/src/web/text/text.tsx +689 -0
  159. package/src/web/textarea/AI_GUIDE.md +141 -0
  160. package/src/web/textarea/index.ts +3 -0
  161. package/src/web/textarea/manifest.json +438 -0
  162. package/src/web/textarea/textarea.css +1 -0
  163. package/src/web/textarea/textarea.tsx +467 -0
  164. package/src/web/tooltip/AI_GUIDE.md +110 -0
  165. package/src/web/tooltip/index.ts +3 -0
  166. package/src/web/tooltip/manifest.json +222 -0
  167. package/src/web/tooltip/tooltip.css +1 -0
  168. package/src/web/tooltip/tooltip.tsx +423 -0
  169. package/src/webview/bottomsheet/AI_GUIDE.md +141 -0
  170. package/src/webview/bottomsheet/bottomsheet.css +1 -0
  171. package/src/webview/bottomsheet/bottomsheet.tsx +603 -0
  172. package/src/webview/bottomsheet/index.ts +4 -0
  173. package/src/webview/bottomsheet/manifest.json +377 -0
  174. package/src/webview/button/AI_GUIDE.md +79 -0
  175. package/src/webview/button/button-ios.css +1 -0
  176. package/src/webview/button/button-ios.tsx +138 -0
  177. package/src/webview/button/button-material.css +1 -0
  178. package/src/webview/button/button-material.tsx +138 -0
  179. package/src/webview/button/index.ts +7 -0
  180. package/src/webview/button/manifest.json +148 -0
  181. package/src/webview/index.ts +7 -0
  182. package/tailwind-preset.cjs +62 -0
  183. package/tailwind-preset.js +62 -0
  184. package/ttdk-manifest.json +10188 -0
@@ -0,0 +1,99 @@
1
+ import * as React from "react";
2
+
3
+ export interface GridBreakpointProps {
4
+ /**
5
+ * Jumlah atau pola template kolom pada grid (grid-template-columns).
6
+ * Nilai angka (misal: 3 atau 12) otomatis dikonversi ke repeat(N, minmax(0, 1fr)).
7
+ * Nilai string (misal: "200px 1fr 2fr", "repeat(4, 1fr)").
8
+ */
9
+ templateColumns?: string | number;
10
+
11
+ /**
12
+ * Jumlah atau pola template baris pada grid (grid-template-rows).
13
+ */
14
+ templateRows?: string | number;
15
+
16
+ /**
17
+ * Jarak celah antar baris dan kolom (gap).
18
+ * Nilai angka (misal: 16) atau string (misal: "16px", "1rem", "var(--ttdk-spacing-16)").
19
+ */
20
+ gap?: string | number;
21
+
22
+ /**
23
+ * Distribusi horizontal keseluruhan grid container (justify-content).
24
+ */
25
+ justifyContent?: "start" | "center" | "end" | "around" | "between" | "evenly";
26
+
27
+ /**
28
+ * Distribusi vertikal baris di dalam grid container (align-content).
29
+ */
30
+ alignContent?: "evenly" | "around" | "between" | "center" | "start" | "end";
31
+ }
32
+ export interface GridProps extends GridBreakpointProps {
33
+ /**
34
+ * Override pada breakpoint sm (min-width: 640px).
35
+ */
36
+ sm?: GridBreakpointProps;
37
+
38
+ /**
39
+ * Override pada breakpoint md (min-width: 768px).
40
+ */
41
+ md?: GridBreakpointProps;
42
+
43
+ /**
44
+ * Override pada breakpoint lg (min-width: 1024px).
45
+ */
46
+ lg?: GridBreakpointProps;
47
+
48
+ /**
49
+ * Override pada breakpoint xl (min-width: 1280px).
50
+ */
51
+ xl?: GridBreakpointProps;
52
+
53
+ /**
54
+ * Override pada breakpoint xxl / 2xl (min-width: 1536px).
55
+ */
56
+ xxl?: GridBreakpointProps;
57
+
58
+ /**
59
+ * Kustomisasi visual granular root kontainer (UiProps).
60
+ */
61
+ ui?: UiProps;
62
+
63
+ /**
64
+ * Class CSS kustom.
65
+ */
66
+ className?: string;
67
+
68
+ /**
69
+ * Style kustom inline.
70
+ */
71
+ style?: React.CSSProperties;
72
+
73
+ /**
74
+ * Konten anak di dalam Grid (<GridItem>).
75
+ */
76
+ children?: any;
77
+ }
78
+
79
+ import { buildGridVars, buildUiVars, UiProps } from "../../core/types";
80
+
81
+ function Grid(props: GridProps) {
82
+ return (
83
+ <div
84
+ className={`ttdk-grid ${props.className || ""}`.trim()}
85
+ style={{
86
+ ...buildGridVars(props),
87
+ ...buildUiVars(props.ui),
88
+ ...((props as any)["style"] || {}),
89
+ ...props.style,
90
+ }}
91
+ >
92
+ <>{props.children}</>
93
+ </div>
94
+ );
95
+ }
96
+
97
+ export default Grid;
98
+
99
+ export { Grid };
@@ -0,0 +1,5 @@
1
+ export { default } from './grid';
2
+ export { default as Grid } from './grid';
3
+ export type { GridProps, GridBreakpointProps } from './grid';
4
+ export { default as GridItem } from './grid-item';
5
+ export type { GridItemProps, GridItemBreakpointProps } from './grid-item'
@@ -0,0 +1,153 @@
1
+ {
2
+ "name": "@ttdk-design-system/grid",
3
+ "component": "Grid",
4
+ "folder": "grid",
5
+ "description": "TTDK Grid component with multi-theme support.",
6
+ "stylesheets": [
7
+ {
8
+ "theme": "common",
9
+ "file": "grid.css",
10
+ "importPath": "web/grid/grid.css"
11
+ }
12
+ ],
13
+ "props": {
14
+ "sm": {
15
+ "name": "sm",
16
+ "type": "GridBreakpointProps",
17
+ "optional": true,
18
+ "default": null,
19
+ "description": "Override pada breakpoint sm (min-width: 640px).",
20
+ "example": null,
21
+ "param": null
22
+ },
23
+ "md": {
24
+ "name": "md",
25
+ "type": "GridBreakpointProps",
26
+ "optional": true,
27
+ "default": null,
28
+ "description": "Override pada breakpoint md (min-width: 768px).",
29
+ "example": null,
30
+ "param": null
31
+ },
32
+ "lg": {
33
+ "name": "lg",
34
+ "type": "GridBreakpointProps",
35
+ "optional": true,
36
+ "default": null,
37
+ "description": "Override pada breakpoint lg (min-width: 1024px).",
38
+ "example": null,
39
+ "param": null
40
+ },
41
+ "xl": {
42
+ "name": "xl",
43
+ "type": "GridBreakpointProps",
44
+ "optional": true,
45
+ "default": null,
46
+ "description": "Override pada breakpoint xl (min-width: 1280px).",
47
+ "example": null,
48
+ "param": null
49
+ },
50
+ "xxl": {
51
+ "name": "xxl",
52
+ "type": "GridBreakpointProps",
53
+ "optional": true,
54
+ "default": null,
55
+ "description": "Override pada breakpoint xxl / 2xl (min-width: 1536px).",
56
+ "example": null,
57
+ "param": null
58
+ },
59
+ "ui": {
60
+ "name": "ui",
61
+ "type": "UiProps",
62
+ "optional": true,
63
+ "default": null,
64
+ "description": "Kustomisasi visual granular root kontainer (UiProps).",
65
+ "example": null,
66
+ "param": null
67
+ },
68
+ "className": {
69
+ "name": "className",
70
+ "type": "string",
71
+ "optional": true,
72
+ "default": null,
73
+ "description": "Class CSS kustom.",
74
+ "example": null,
75
+ "param": null
76
+ },
77
+ "style": {
78
+ "name": "style",
79
+ "type": "any",
80
+ "optional": true,
81
+ "default": null,
82
+ "description": "Style kustom inline.",
83
+ "example": null,
84
+ "param": null
85
+ },
86
+ "children": {
87
+ "name": "children",
88
+ "type": "any",
89
+ "optional": true,
90
+ "default": null,
91
+ "description": "Konten anak di dalam Grid (<GridItem>).",
92
+ "example": null,
93
+ "param": null
94
+ }
95
+ },
96
+ "subInterfaces": {
97
+ "GridBreakpointProps": {
98
+ "templateColumns": {
99
+ "name": "templateColumns",
100
+ "type": "string | number",
101
+ "optional": true,
102
+ "default": null,
103
+ "description": "Jumlah atau pola template kolom pada grid (grid-template-columns). Nilai angka (misal: 3 atau 12) otomatis dikonversi ke repeat(N, minmax(0, 1fr)). Nilai string (misal: \"200px 1fr 2fr\", \"repeat(4, 1fr)\").",
104
+ "example": null,
105
+ "param": null
106
+ },
107
+ "templateRows": {
108
+ "name": "templateRows",
109
+ "type": "string | number",
110
+ "optional": true,
111
+ "default": null,
112
+ "description": "Jumlah atau pola template baris pada grid (grid-template-rows).",
113
+ "example": null,
114
+ "param": null
115
+ },
116
+ "gap": {
117
+ "name": "gap",
118
+ "type": "string | number",
119
+ "optional": true,
120
+ "default": null,
121
+ "description": "Jarak celah antar baris dan kolom (gap). Nilai angka (misal: 16) atau string (misal: \"16px\", \"1rem\", \"var(--ttdk-spacing-16)\").",
122
+ "example": null,
123
+ "param": null
124
+ },
125
+ "justifyContent": {
126
+ "name": "justifyContent",
127
+ "type": "'start' | 'center' | 'end' | 'around' | 'between' | 'evenly'",
128
+ "optional": true,
129
+ "default": null,
130
+ "description": "Distribusi horizontal keseluruhan grid container (justify-content).",
131
+ "example": null,
132
+ "param": null
133
+ },
134
+ "alignContent": {
135
+ "name": "alignContent",
136
+ "type": "'evenly' | 'around' | 'between' | 'center' | 'start' | 'end'",
137
+ "optional": true,
138
+ "default": null,
139
+ "description": "Distribusi vertikal baris di dalam grid container (align-content).",
140
+ "example": null,
141
+ "param": null
142
+ }
143
+ }
144
+ },
145
+ "supportedFrameworks": [
146
+ "react",
147
+ "vue",
148
+ "svelte"
149
+ ],
150
+ "themes": [
151
+ "tw"
152
+ ]
153
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * TTDK Design System — Web Module (REACT)
3
+ */
4
+
5
+ export { default as Accordion } from './accordion/accordion';
6
+ export * from './accordion';
7
+
8
+ export { default as Alert } from './alert/alert';
9
+ export * from './alert';
10
+
11
+ export { default as Avatar } from './avatar/avatar';
12
+ export * from './avatar';
13
+
14
+ export { default as Badge } from './badge/badge';
15
+ export * from './badge';
16
+
17
+ export { default as Banner } from './banner/banner';
18
+ export * from './banner';
19
+
20
+ export { default as Breadcrumb } from './breadcrumb/breadcrumb';
21
+ export * from './breadcrumb';
22
+
23
+ export { default as Button } from './button/button';
24
+ export * from './button';
25
+
26
+ export { default as Calendar } from './calendar/calendar';
27
+ export * from './calendar';
28
+
29
+ export { default as Card } from './card/card';
30
+ export * from './card';
31
+
32
+ export { default as Checkbox } from './checkbox/checkbox';
33
+ export * from './checkbox';
34
+
35
+ export { default as Chip } from './chip/chip';
36
+ export * from './chip';
37
+
38
+ export { default as Dropdown } from './dropdown/dropdown';
39
+ export * from './dropdown';
40
+
41
+ export { default as Flex } from './flex/flex';
42
+ export * from './flex';
43
+
44
+ export { default as Grid } from './grid/grid';
45
+ export * from './grid';
46
+
47
+ export { default as Input } from './input/input';
48
+ export * from './input';
49
+
50
+ export { default as InputNumber } from './input-number/input-number';
51
+ export * from './input-number';
52
+
53
+ export { default as Modal } from './modal/modal';
54
+ export * from './modal';
55
+
56
+ export { default as Pagination, PaginationContent, PaginationItem, PaginationLink, PaginationPrevious, PaginationNext, PaginationFirst, PaginationLast, PaginationEllipsis } from './pagination';
57
+ export * from './pagination';
58
+
59
+ export { default as Popover } from './popover/popover';
60
+ export * from './popover';
61
+
62
+ export { default as Radio } from './radio/radio';
63
+ export * from './radio';
64
+
65
+ export { default as Selectbox } from './selectbox/selectbox';
66
+ export * from './selectbox';
67
+
68
+ export { default as Sonner, default as Toaster, toast } from './sonner';
69
+ export * from './sonner';
70
+
71
+ export { default as Table, default as DataTable, TableHeader, TableBody, TableFooter, TableRow, TableHead, TableCell, TableCaption, TableEmpty } from './table';
72
+ export type { TableProps, TableUiProps } from './table/table';
73
+ export * from './table';
74
+
75
+ export { default as Tabs } from './tabs/tabs';
76
+ export * from './tabs';
77
+
78
+ export { default as Text } from './text/text';
79
+ export * from './text';
80
+
81
+ export { default as Textarea } from './textarea/textarea';
82
+ export * from './textarea';
83
+
84
+ export { default as Tooltip } from './tooltip/tooltip';
85
+ export * from './tooltip';
86
+
@@ -0,0 +1,159 @@
1
+ # <Input /> — TTDK Component Reference
2
+
3
+ Komponen Input TTDK sesuai spesifikasi Anatomy Desain: 1. Field title (14px Semibold, #141313) 2. (Opsional) label (12px Regular, #9698A2) 3. Border radius 8px 4. Icon left / right (24px) 5. Field content (14px Regular, #141313, placeholder #9698A2) 6. Additional information / Helper text (12px Regular, #3C4245)
4
+
5
+ ## 1. Stylesheets & Theming (Pure CSS)
6
+ Import the corresponding stylesheet for the theme you wish to use:
7
+ - **COMMON Theme**: `import "@ttdk-design-system/library-<react|vue|svelte>/web/input/input.css";`
8
+
9
+ ## 2. Subpath Component Import
10
+ ```ts
11
+ // React
12
+ import Input from "@ttdk-design-system/library-react/web/input";
13
+
14
+ // Vue 3
15
+ import Input from "@ttdk-design-system/library-vue/web/input";
16
+
17
+ // Svelte
18
+ import Input from "@ttdk-design-system/library-svelte/web/input";
19
+ ```
20
+
21
+ ## 3. Props & API Reference
22
+
23
+ | Prop | Type | Default | Description |
24
+ | :--- | :--- | :--- | :--- |
25
+ | `label?` | `string` | `-` | Teks label judul field yang ditampilkan di atas input (14px Semibold, #141313). |
26
+ | `labelStyle?` | `UiProps` | `-` | Style kustom untuk elemen label judul field (UiProps). |
27
+ | `labelClass?` | `string` | `-` | Class CSS kustom untuk elemen label judul field. |
28
+ | `wrapperStyle?` | `UiProps` | `-` | Style kustom untuk elemen kontainer input wrapper (UiProps). |
29
+ | `wrapperClass?` | `string` | `-` | Class CSS kustom untuk elemen kontainer input wrapper. |
30
+ | `inputStyle?` | `UiProps` | `-` | Style kustom untuk elemen input control HTML (UiProps). |
31
+ | `inputClass?` | `string` | `-` | Class CSS kustom untuk elemen input control HTML. |
32
+ | `errorMessageStyle?` | `UiProps` | `-` | Style kustom untuk elemen pesan error validasi (UiProps). |
33
+ | `errorMessageClass?` | `string` | `-` | Class CSS kustom untuk elemen pesan error validasi. |
34
+ | `helperTextStyle?` | `UiProps` | `-` | Style kustom untuk elemen helper text (UiProps). |
35
+ | `helperTextClass?` | `string` | `-` | Class CSS kustom untuk elemen helper text. |
36
+ | `optional?` | `boolean` | `-` | Menandai field sebagai opsi opsional dengan menambahkan teks '(Opsional)' (12px Regular, #9698A2). |
37
+ | `optionalText?` | `string` | `(Opsional)` | Kustomisasi teks keterangan opsional. |
38
+ | `placeholder?` | `string` | `-` | Nilai teks placeholder saat input kosong (#9698A2). |
39
+ | `value?` | `string | number` | `-` | Nilai terkontrol (controlled value) pada input. |
40
+ | `defaultValue?` | `string | number` | `-` | Nilai awal tidak terkontrol (uncontrolled initial value). |
41
+ | `type?` | `string` | `text` | Tipe field input HTML standar. |
42
+ | `name?` | `string` | `-` | Nama form field HTML untuk integrasi formulir. |
43
+ | `id?` | `string` | `-` | Identifier unik elemen input. |
44
+ | `error?` | `boolean` | `false` | Status apakah input sedang dalam kondisi error / tidak valid. |
45
+ | `errorMessage?` | `string` | `-` | Pesan teks penjelasan kesalahan validasi di bawah field. |
46
+ | `helperText?` | `string` | `-` | Teks petunjuk atau keterangan bantuan di bawah field (12px Regular, #3C4245). |
47
+ | `helperTextPosition?` | `'top' | 'bottom'` | `-` | Posisi teks helper |
48
+ | `size?` | `'sm' | 'md' | 'lg'` | `md` | Skala ukuran input field. - `'sm'`: 36px - `'md'`: 48px (standar) - `'lg'`: 56px |
49
+ | `rounded?` | `'none' | 'sm' | 'md' | 'lg' | 'full'` | `md` | Bentuk sudut kelengkungan input. - `'none'`: 0px - `'sm'`: 4px - `'md'`: 8px (standar desain) - `'lg'`: 12px - `'full'`: 9999px (kapsul) |
50
+ | `block?` | `boolean` | `false` | Menjadikan lebar field input memenuhi kontainer penuh (full-width 100%). |
51
+ | `disabled?` | `boolean` | `false` | Status apakah field dinonaktifkan (disabled). |
52
+ | `readOnly?` | `boolean` | `false` | Status apakah field bersifat hanya-baca (readonly). |
53
+ | `required?` | `boolean` | `false` | Menandai field sebagai input wajib diisi (menampilkan tanda bintang merah *). |
54
+ | `iconLeft?` | `any` | `-` | Ikon di sebelah kiri dalam input (ukuran 20-24px, misal: Calendar, Search, User). |
55
+ | `iconRight?` | `any` | `-` | Ikon di sebelah kanan dalam input (ukuran 20-24px, misal: Chevron-down, Eye, Close). |
56
+ | `addonLeft?` | `string | any` | `-` | Addon / teks prefix di sebelah kiri luar input (misal: 'Text', '+62 (IDN)'). |
57
+ | `addonRight?` | `string | any` | `-` | Addon / teks suffix di sebelah kanan luar input (misal: 'Text', '.com', 'kg'). |
58
+ | `autoComplete?` | `string` | `-` | Konfigurasi atribut autocomplete HTML. |
59
+ | `maxLength?` | `number` | `-` | Batas maksimum panjang karakter. |
60
+ | `minLength?` | `number` | `-` | Batas minimum panjang karakter. |
61
+ | `min?` | `number | string` | `-` | Nilai minimum untuk input bertipe number atau date. |
62
+ | `max?` | `number | string` | `-` | Nilai maksimum untuk input bertipe number atau date. |
63
+ | `style?` | `any` | `-` | Inline CSS style object native. |
64
+ | `ui?` | `UiProps` | `-` | Kustomisasi visual granular root / form-item (UiProps). |
65
+ | `onChange?` | `(event: any) => void` | `-` | Callback event saat nilai input berubah. |
66
+ | `onInput?` | `(event: any) => void` | `-` | Callback event saat pengguna mengetik (input event). |
67
+ | `onBlur?` | `(event: any) => void` | `-` | Callback event saat field input kehilangan fokus. |
68
+ | `onFocus?` | `(event: any) => void` | `-` | Callback event saat field input mendapatkan fokus. |
69
+ | `inputRef?` | `any` | `-` | Ref instance elemen input HTML untuk akses kontrol DOM langsung (focus, blur, select). |
70
+ | `className?` | `string` | `-` | Class CSS kustom. |
71
+ | `onKeyDown?` | `(event: any) => void` | `-` | Callback event tombol keyboard ditekan. |
72
+ | `onKeyUp?` | `(event: any) => void` | `-` | Callback event tombol keyboard dilepaskan. |
73
+ | `loading?` | `boolean` | `false` | Menampilkan spinner dan menonaktifkan interaksi field sementara menunggu proses async. |
74
+
75
+ ## 4. Usage Examples
76
+
77
+ ### React Example
78
+ ```tsx
79
+ import { useState } from "react";
80
+ import Input from "@ttdk-design-system/library-react/web/input";
81
+ import "@ttdk-design-system/library-react/web/input/input.css";
82
+
83
+ export function Example() {
84
+ const [email, setEmail] = useState("");
85
+
86
+ return (
87
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '16px', maxWidth: '400px' }}>
88
+ <Input
89
+ label="Alamat Email"
90
+ placeholder="nama@kemkes.go.id"
91
+ value={email}
92
+ required
93
+ helperText="Gunakan email kedinasan terdaftar."
94
+ onChange={(e) => setEmail(e.target.value)}
95
+ />
96
+ <Input
97
+ label="Nomor STR"
98
+ placeholder="Masukkan nomor STR tenaga kesehatan"
99
+ optional
100
+ />
101
+ </div>
102
+ );
103
+ }
104
+ ```
105
+
106
+ ### Vue 3 Example
107
+ ```vue
108
+ <script setup lang="ts">
109
+ import { ref } from "vue";
110
+ import Input from "@ttdk-design-system/library-vue/web/input";
111
+ import "@ttdk-design-system/library-vue/web/input/input.css";
112
+
113
+ const email = ref("");
114
+ </script>
115
+
116
+ <template>
117
+ <div style="display: flex; flex-direction: column; gap: 16px; max-width: 400px;">
118
+ <Input
119
+ label="Alamat Email"
120
+ placeholder="nama@kemkes.go.id"
121
+ :value="email"
122
+ :required="true"
123
+ helper-text="Gunakan email kedinasan terdaftar."
124
+ @input="(e: any) => (email = e.target.value)"
125
+ />
126
+ <Input
127
+ label="Nomor STR"
128
+ placeholder="Masukkan nomor STR tenaga kesehatan"
129
+ :optional="true"
130
+ />
131
+ </div>
132
+ </template>
133
+ ```
134
+
135
+ ### Svelte Example
136
+ ```svelte
137
+ <script lang="ts">
138
+ import Input from "@ttdk-design-system/library-svelte/web/input";
139
+ import "@ttdk-design-system/library-svelte/web/input/input.css";
140
+
141
+ let email = "";
142
+ </script>
143
+
144
+ <div style="display: flex; flex-direction: column; gap: 16px; max-width: 400px;">
145
+ <Input
146
+ label="Alamat Email"
147
+ placeholder="nama@kemkes.go.id"
148
+ value={email}
149
+ required={true}
150
+ helperText="Gunakan email kedinasan terdaftar."
151
+ on:input={(e) => (email = e.target.value)}
152
+ />
153
+ <Input
154
+ label="Nomor STR"
155
+ placeholder="Masukkan nomor STR tenaga kesehatan"
156
+ optional={true}
157
+ />
158
+ </div>
159
+ ```
@@ -0,0 +1,3 @@
1
+ export { default as Input } from './input';
2
+ export { default } from './input';
3
+ export type { InputProps, InputUiProps } from './input'
@@ -0,0 +1 @@
1
+ .ttdk-form-item{gap:var(--ttdk-spacing-xxs);box-sizing:border-box;width:100%;font-family:var(--ttdk-font-sans);flex-direction:column;display:flex}.ttdk-form-item[data-block=true]{width:100%}.ttdk-form-label{font-size:var(--ttdk-font-size-14);font-weight:var(--ttdk-font-weight-semibold);line-height:var(--ttdk-font-size-20);color:var(--ttdk-ui-color,var(--ttdk-text-icon-primary));align-items:center;gap:var(--ttdk-spacing-xxs);user-select:none;display:flex}.dark .ttdk-form-label{color:var(--ttdk-ui-color,var(--ttdk-text-icon-primary))}.ttdk-form-required{color:var(--ttdk-stroke-status-error);font-weight:var(--ttdk-font-weight-bold)}.dark .ttdk-form-required{color:var(--ttdk-stroke-status-error)}.ttdk-form-optional{font-size:var(--ttdk-font-size-12);font-weight:var(--ttdk-font-weight-regular);line-height:var(--ttdk-font-size-18);color:var(--ttdk-text-icon-disabled);margin-left:var(--ttdk-spacing-none)}.dark .ttdk-form-optional{color:var(--ttdk-text-icon-disabled)}.ttdk-input-wrapper{background:var(--ttdk-bg-base-primary);border:var(--ttdk-stroke-width-thin) solid var(--ttdk-stroke-subtle);border-radius:var(--ttdk-radius-input-lg);box-sizing:border-box;align-items:stretch;width:100%;height:48px;transition:border-color .15s,box-shadow .15s,background-color .15s;display:flex;overflow:hidden}.dark .ttdk-input-wrapper{background:var(--ttdk-bg-base-primary);border-color:var(--ttdk-stroke-subtle)}.ttdk-input-wrapper[data-filled=true],.dark .ttdk-input-wrapper[data-filled=true]{border-color:var(--ttdk-stroke-strong)}.ttdk-input-wrapper:focus-within{box-shadow:0 0 0 3px color-mix(in srgb, var(--ttdk-stroke-border-focus) 15%, transparent);border-color:var(--ttdk-stroke-border-focus)!important}.dark .ttdk-input-wrapper:focus-within{box-shadow:0 0 0 3px color-mix(in srgb, var(--ttdk-stroke-border-focus) 25%, transparent);border-color:var(--ttdk-stroke-border-focus)!important}.ttdk-input-wrapper[data-error=true]{border-color:var(--ttdk-stroke-status-error)!important}.ttdk-input-wrapper[data-error=true]:focus-within{box-shadow:0 0 0 3px color-mix(in srgb, var(--ttdk-stroke-status-error) 15%, transparent);border-color:var(--ttdk-stroke-status-error)!important}.dark .ttdk-input-wrapper[data-error=true]{border-color:var(--ttdk-stroke-status-error)!important}.ttdk-form-item[data-error=true] .ttdk-form-label,.dark .ttdk-form-item[data-error=true] .ttdk-form-label{color:var(--ttdk-text-icon-status-error)}.ttdk-input-wrapper[data-disabled=true],.ttdk-form-item[data-disabled=true] .ttdk-input-wrapper{cursor:not-allowed;opacity:.85;background:var(--ttdk-bg-secondary-disabled)!important;border-color:var(--ttdk-stroke-subtle)!important}.dark .ttdk-input-wrapper[data-disabled=true],.dark .ttdk-form-item[data-disabled=true] .ttdk-input-wrapper{opacity:.75;background:var(--ttdk-bg-secondary-disabled)!important;border-color:var(--ttdk-stroke-subtle)!important}.ttdk-input-inner{align-items:center;gap:var(--ttdk-spacing-sm);min-width:0;height:100%;padding:0 var(--ttdk-spacing-sm);flex:1;display:flex;position:relative}.ttdk-input-icon{width:var(--ttdk-font-size-24);height:var(--ttdk-font-size-24);color:var(--ttdk-text-icon-disabled);user-select:none;flex-shrink:0;justify-content:center;align-items:center;display:inline-flex}.dark .ttdk-input-icon{color:var(--ttdk-text-icon-disabled)}.ttdk-input-icon svg{width:var(--ttdk-font-size-24);height:var(--ttdk-font-size-24)}.ttdk-input-icon-left{margin-left:var(--ttdk-spacing-none);margin-right:var(--ttdk-spacing-none)}.ttdk-input-icon-right{margin-right:var(--ttdk-spacing-none);margin-left:var(--ttdk-spacing-none)}.ttdk-input-spinner{flex-shrink:0;justify-content:center;align-items:center;display:inline-flex}.ttdk-input-spinner svg{fill:none;stroke:currentColor;stroke-width:2.2px;stroke-linecap:round;width:20px;height:20px;animation:1.2s steps(12,end) infinite ttdk-input-spin}@keyframes ttdk-input-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.ttdk-input-control{width:100%;min-width:0;font-size:var(--ttdk-font-size-14);font-weight:var(--ttdk-font-weight-regular);line-height:var(--ttdk-line-height-body);height:100%;color:var(--ttdk-ui-color,var(--ttdk-text-icon-primary));box-sizing:border-box;font-family:var(--ttdk-font-sans);background:0 0;border:none;outline:none;flex:1;padding:0}.dark .ttdk-input-control{color:var(--ttdk-ui-color,var(--ttdk-text-icon-primary))}.ttdk-input-control::placeholder{color:var(--ttdk-text-icon-disabled);opacity:1}.dark .ttdk-input-control::placeholder{color:var(--ttdk-text-icon-disabled)}.ttdk-input-control:disabled{cursor:not-allowed;color:var(--ttdk-text-icon-disabled)}.dark .ttdk-input-control:disabled{color:var(--ttdk-text-icon-disabled)}.ttdk-input-wrapper[data-size=sm]{height:36px}.ttdk-input-wrapper[data-size=sm] .ttdk-input-control{font-size:var(--ttdk-font-size-12)}.ttdk-input-wrapper[data-size=sm] .ttdk-input-icon,.ttdk-input-wrapper[data-size=sm] .ttdk-input-icon svg{width:var(--ttdk-font-size-20);height:var(--ttdk-font-size-20)}.ttdk-input-wrapper[data-size=sm] .ttdk-input-icon.ttdk-input-spinner,.ttdk-input-wrapper[data-size=sm] .ttdk-input-icon.ttdk-input-spinner svg,.ttdk-input-wrapper[data-size=sm] .ttdk-input-spinner,.ttdk-input-wrapper[data-size=sm] .ttdk-input-spinner svg{width:16px;height:16px}.ttdk-input-wrapper[data-size=sm] .ttdk-input-addon{padding:0 var(--ttdk-spacing-sm);font-size:var(--ttdk-font-size-12)}.ttdk-input-wrapper[data-size=md]{height:48px}.ttdk-input-wrapper[data-size=md] .ttdk-input-control{font-size:var(--ttdk-font-size-14)}.ttdk-input-wrapper[data-size=md] .ttdk-input-icon.ttdk-input-spinner,.ttdk-input-wrapper[data-size=md] .ttdk-input-icon.ttdk-input-spinner svg,.ttdk-input-wrapper[data-size=md] .ttdk-input-spinner,.ttdk-input-wrapper[data-size=md] .ttdk-input-spinner svg{width:20px;height:20px}.ttdk-input-wrapper[data-size=lg]{height:56px}.ttdk-input-wrapper[data-size=lg] .ttdk-input-control{font-size:var(--ttdk-font-size-16)}.ttdk-input-wrapper[data-size=lg] .ttdk-input-icon.ttdk-input-spinner,.ttdk-input-wrapper[data-size=lg] .ttdk-input-icon.ttdk-input-spinner svg,.ttdk-input-wrapper[data-size=lg] .ttdk-input-spinner,.ttdk-input-wrapper[data-size=lg] .ttdk-input-spinner svg{width:24px;height:24px}.ttdk-input-wrapper[data-rounded=none]{border-radius:var(--ttdk-radius-input-none)}.ttdk-input-wrapper[data-rounded=xs]{border-radius:var(--ttdk-radius-input-xs)}.ttdk-input-wrapper[data-rounded=sm]{border-radius:var(--ttdk-radius-input-sm)}.ttdk-input-wrapper[data-rounded=md]{border-radius:var(--ttdk-radius-input-md)}.ttdk-input-wrapper[data-rounded=lg]{border-radius:var(--ttdk-radius-input-lg)}.ttdk-input-wrapper[data-rounded=xl]{border-radius:var(--ttdk-radius-input-xl)}.ttdk-input-wrapper[data-rounded=full]{border-radius:var(--ttdk-radius-input-full)}.ttdk-input-addon{padding:0 var(--ttdk-spacing-md);font-size:var(--ttdk-font-size-14);font-weight:var(--ttdk-font-weight-medium);color:var(--ttdk-text-icon-secondary);background:var(--ttdk-bg-secondary-disabled);border-color:var(--ttdk-stroke-subtle);user-select:none;white-space:nowrap;box-sizing:border-box;justify-content:center;align-items:center;display:flex}.dark .ttdk-input-addon{background:var(--ttdk-bg-secondary-disabled);color:var(--ttdk-text-icon-secondary);border-color:var(--ttdk-stroke-subtle)}.ttdk-input-addon-left{border-right:var(--ttdk-stroke-width-thin) solid var(--ttdk-stroke-subtle)}.dark .ttdk-input-addon-left{border-right-color:var(--ttdk-stroke-subtle)}.ttdk-input-addon-right{border-left:var(--ttdk-stroke-width-thin) solid var(--ttdk-stroke-subtle)}.dark .ttdk-input-addon-right{border-left-color:var(--ttdk-stroke-subtle)}.ttdk-input-wrapper[data-disabled=true] .ttdk-input-addon,.dark .ttdk-input-wrapper[data-disabled=true] .ttdk-input-addon{background:var(--ttdk-bg-secondary-disabled);color:var(--ttdk-text-icon-disabled)}.ttdk-input-addon-btn,.ttdk-input-addon-select{align-items:center;gap:var(--ttdk-spacing-xs);font-family:inherit;font-size:var(--ttdk-font-size-14);font-weight:var(--ttdk-font-weight-medium);color:var(--ttdk-text-icon-primary);cursor:pointer;user-select:none;background:0 0;border:none;outline:none;height:100%;margin:0;padding:0;display:inline-flex}.dark .ttdk-input-addon-btn,.dark .ttdk-input-addon-select{color:var(--ttdk-text-icon-primary)}.ttdk-input-addon-btn:hover,.ttdk-input-addon-select:hover{color:var(--ttdk-brand-default)}.ttdk-input-addon-btn svg,.ttdk-input-addon-select svg{width:var(--ttdk-font-size-16);height:var(--ttdk-font-size-16);color:var(--ttdk-text-icon-disabled);transition:transform .2s}.ttdk-input-addon-btn[aria-expanded=true] svg,.ttdk-input-addon-btn.active svg{transform:rotate(180deg)}.ttdk-input-addon select{font-family:inherit;font-size:var(--ttdk-font-size-14);font-weight:var(--ttdk-font-weight-medium);color:var(--ttdk-text-icon-primary);cursor:pointer;padding-right:var(--ttdk-spacing-xxs);background:0 0;border:none;outline:none}.dark .ttdk-input-addon select{color:var(--ttdk-text-icon-primary);background:var(--ttdk-bg-base-primary)}.ttdk-input-addon-dropdown{align-items:center;height:100%;display:flex;position:relative}.ttdk-input-dropdown-menu{top:calc(100% + var(--ttdk-spacing-xs));left:calc(-1 * var(--ttdk-spacing-md));z-index:50;background:var(--ttdk-bg-base-primary);border:var(--ttdk-stroke-width-thin) solid var(--ttdk-stroke-subtle);border-radius:var(--ttdk-radius-input-lg);min-width:220px;box-shadow:var(--ttdk-shadow-md);padding:var(--ttdk-spacing-xs);gap:var(--ttdk-spacing-xxxs);box-sizing:border-box;flex-direction:column;max-height:240px;display:flex;position:absolute;overflow-y:auto}.dark .ttdk-input-dropdown-menu{background:var(--ttdk-bg-base-primary);border-color:var(--ttdk-stroke-subtle);box-shadow:var(--ttdk-shadow-md)}.ttdk-input-dropdown-item{justify-content:space-between;align-items:center;gap:var(--ttdk-spacing-xs);padding:var(--ttdk-spacing-xs) var(--ttdk-spacing-sm);font-size:var(--ttdk-font-size-14);color:var(--ttdk-text-icon-primary);border-radius:var(--ttdk-radius-input-md);cursor:pointer;text-align:left;box-sizing:border-box;background:0 0;border:none;width:100%;transition:background-color .15s,color .15s;display:flex}.dark .ttdk-input-dropdown-item{color:var(--ttdk-text-icon-primary)}.ttdk-input-dropdown-item:hover,.ttdk-input-dropdown-item[data-selected=true]{background:var(--ttdk-brand-subtle);color:var(--ttdk-brand-default);font-weight:var(--ttdk-font-weight-medium)}.dark .ttdk-input-dropdown-item:hover,.dark .ttdk-input-dropdown-item[data-selected=true]{background:color-mix(in srgb, var(--ttdk-brand-default) 15%, transparent);color:var(--ttdk-stroke-border-focus)}.ttdk-form-helper-text{font-size:var(--ttdk-font-size-12);font-weight:var(--ttdk-font-weight-regular);color:var(--ttdk-text-icon-secondary);line-height:var(--ttdk-font-size-18);min-height:var(--ttdk-font-size-18)}.dark .ttdk-form-helper-text{color:var(--ttdk-text-icon-secondary)}.ttdk-form-error-msg{align-items:center;gap:var(--ttdk-spacing-xxs);font-size:var(--ttdk-font-size-12);color:var(--ttdk-text-icon-status-error);font-weight:var(--ttdk-font-weight-medium);line-height:var(--ttdk-font-size-18);min-height:var(--ttdk-font-size-18);display:flex}.dark .ttdk-form-error-msg{color:var(--ttdk-text-icon-status-error)}.ttdk-form-error-icon{width:var(--ttdk-font-size-14);height:var(--ttdk-font-size-14);flex-shrink:0}.ttdk-form-error-icon path{fill-rule:evenodd;clip-rule:evenodd}