tyrell-react 1.0.0-TC10

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 (139) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +410 -0
  3. package/dist/components/TyButton.d.ts +50 -0
  4. package/dist/components/TyButton.d.ts.map +1 -0
  5. package/dist/components/TyButton.js +68 -0
  6. package/dist/components/TyButton.js.map +1 -0
  7. package/dist/components/TyCalendar.d.ts +63 -0
  8. package/dist/components/TyCalendar.d.ts.map +1 -0
  9. package/dist/components/TyCalendar.js +122 -0
  10. package/dist/components/TyCalendar.js.map +1 -0
  11. package/dist/components/TyCalendarMonth.d.ts +32 -0
  12. package/dist/components/TyCalendarMonth.d.ts.map +1 -0
  13. package/dist/components/TyCalendarMonth.js +54 -0
  14. package/dist/components/TyCalendarMonth.js.map +1 -0
  15. package/dist/components/TyCalendarNavigation.d.ts +21 -0
  16. package/dist/components/TyCalendarNavigation.d.ts.map +1 -0
  17. package/dist/components/TyCalendarNavigation.js +50 -0
  18. package/dist/components/TyCalendarNavigation.js.map +1 -0
  19. package/dist/components/TyCheckbox.d.ts +39 -0
  20. package/dist/components/TyCheckbox.d.ts.map +1 -0
  21. package/dist/components/TyCheckbox.js +79 -0
  22. package/dist/components/TyCheckbox.js.map +1 -0
  23. package/dist/components/TyCopy.d.ts +21 -0
  24. package/dist/components/TyCopy.d.ts.map +1 -0
  25. package/dist/components/TyCopy.js +42 -0
  26. package/dist/components/TyCopy.js.map +1 -0
  27. package/dist/components/TyDatePicker.d.ts +45 -0
  28. package/dist/components/TyDatePicker.d.ts.map +1 -0
  29. package/dist/components/TyDatePicker.js +114 -0
  30. package/dist/components/TyDatePicker.js.map +1 -0
  31. package/dist/components/TyDropdown.d.ts +51 -0
  32. package/dist/components/TyDropdown.d.ts.map +1 -0
  33. package/dist/components/TyDropdown.js +109 -0
  34. package/dist/components/TyDropdown.js.map +1 -0
  35. package/dist/components/TyIcon.d.ts +17 -0
  36. package/dist/components/TyIcon.d.ts.map +1 -0
  37. package/dist/components/TyIcon.js +41 -0
  38. package/dist/components/TyIcon.js.map +1 -0
  39. package/dist/components/TyInput.d.ts +65 -0
  40. package/dist/components/TyInput.d.ts.map +1 -0
  41. package/dist/components/TyInput.js +105 -0
  42. package/dist/components/TyInput.js.map +1 -0
  43. package/dist/components/TyModal.d.ts +29 -0
  44. package/dist/components/TyModal.d.ts.map +1 -0
  45. package/dist/components/TyModal.js +74 -0
  46. package/dist/components/TyModal.js.map +1 -0
  47. package/dist/components/TyMultiselect.d.ts +51 -0
  48. package/dist/components/TyMultiselect.d.ts.map +1 -0
  49. package/dist/components/TyMultiselect.js +103 -0
  50. package/dist/components/TyMultiselect.js.map +1 -0
  51. package/dist/components/TyOption.d.ts +10 -0
  52. package/dist/components/TyOption.d.ts.map +1 -0
  53. package/dist/components/TyOption.js +25 -0
  54. package/dist/components/TyOption.js.map +1 -0
  55. package/dist/components/TyPopup.d.ts +24 -0
  56. package/dist/components/TyPopup.d.ts.map +1 -0
  57. package/dist/components/TyPopup.js +61 -0
  58. package/dist/components/TyPopup.js.map +1 -0
  59. package/dist/components/TyRadio.d.ts +20 -0
  60. package/dist/components/TyRadio.d.ts.map +1 -0
  61. package/dist/components/TyRadio.js +31 -0
  62. package/dist/components/TyRadio.js.map +1 -0
  63. package/dist/components/TyRadioGroup.d.ts +40 -0
  64. package/dist/components/TyRadioGroup.d.ts.map +1 -0
  65. package/dist/components/TyRadioGroup.js +58 -0
  66. package/dist/components/TyRadioGroup.js.map +1 -0
  67. package/dist/components/TyResizeObserver.d.ts +11 -0
  68. package/dist/components/TyResizeObserver.d.ts.map +1 -0
  69. package/dist/components/TyResizeObserver.js +28 -0
  70. package/dist/components/TyResizeObserver.js.map +1 -0
  71. package/dist/components/TyScrollContainer.d.ts +25 -0
  72. package/dist/components/TyScrollContainer.d.ts.map +1 -0
  73. package/dist/components/TyScrollContainer.js +43 -0
  74. package/dist/components/TyScrollContainer.js.map +1 -0
  75. package/dist/components/TyStep.d.ts +17 -0
  76. package/dist/components/TyStep.d.ts.map +1 -0
  77. package/dist/components/TyStep.js +35 -0
  78. package/dist/components/TyStep.js.map +1 -0
  79. package/dist/components/TySwitch.d.ts +35 -0
  80. package/dist/components/TySwitch.d.ts.map +1 -0
  81. package/dist/components/TySwitch.js +54 -0
  82. package/dist/components/TySwitch.js.map +1 -0
  83. package/dist/components/TyTab.d.ts +13 -0
  84. package/dist/components/TyTab.d.ts.map +1 -0
  85. package/dist/components/TyTab.js +32 -0
  86. package/dist/components/TyTab.js.map +1 -0
  87. package/dist/components/TyTabs.d.ts +23 -0
  88. package/dist/components/TyTabs.d.ts.map +1 -0
  89. package/dist/components/TyTabs.js +48 -0
  90. package/dist/components/TyTabs.js.map +1 -0
  91. package/dist/components/TyTag.d.ts +22 -0
  92. package/dist/components/TyTag.d.ts.map +1 -0
  93. package/dist/components/TyTag.js +45 -0
  94. package/dist/components/TyTag.js.map +1 -0
  95. package/dist/components/TyTextarea.d.ts +37 -0
  96. package/dist/components/TyTextarea.d.ts.map +1 -0
  97. package/dist/components/TyTextarea.js +93 -0
  98. package/dist/components/TyTextarea.js.map +1 -0
  99. package/dist/components/TyTooltip.d.ts +17 -0
  100. package/dist/components/TyTooltip.d.ts.map +1 -0
  101. package/dist/components/TyTooltip.js +40 -0
  102. package/dist/components/TyTooltip.js.map +1 -0
  103. package/dist/components/TyWizard.d.ts +26 -0
  104. package/dist/components/TyWizard.d.ts.map +1 -0
  105. package/dist/components/TyWizard.js +50 -0
  106. package/dist/components/TyWizard.js.map +1 -0
  107. package/dist/components/index.d.ts +105 -0
  108. package/dist/components/index.d.ts.map +1 -0
  109. package/dist/components/index.js +112 -0
  110. package/dist/components/index.js.map +1 -0
  111. package/package.json +46 -0
  112. package/src/components/EventConventionTest.tsx +155 -0
  113. package/src/components/TyButton.tsx +145 -0
  114. package/src/components/TyCalendar.tsx +244 -0
  115. package/src/components/TyCalendarMonth.tsx +108 -0
  116. package/src/components/TyCalendarNavigation.tsx +91 -0
  117. package/src/components/TyCheckbox.tsx +149 -0
  118. package/src/components/TyCopy.tsx +78 -0
  119. package/src/components/TyDatePicker.tsx +216 -0
  120. package/src/components/TyDropdown.tsx +218 -0
  121. package/src/components/TyIcon.tsx +72 -0
  122. package/src/components/TyInput.tsx +207 -0
  123. package/src/components/TyModal.tsx +142 -0
  124. package/src/components/TyMultiselect.tsx +200 -0
  125. package/src/components/TyOption.tsx +42 -0
  126. package/src/components/TyPopup.tsx +111 -0
  127. package/src/components/TyRadio.tsx +56 -0
  128. package/src/components/TyRadioGroup.tsx +121 -0
  129. package/src/components/TyResizeObserver.tsx +54 -0
  130. package/src/components/TyScrollContainer.tsx +87 -0
  131. package/src/components/TyStep.tsx +71 -0
  132. package/src/components/TySwitch.tsx +108 -0
  133. package/src/components/TyTab.tsx +63 -0
  134. package/src/components/TyTabs.tsx +93 -0
  135. package/src/components/TyTag.tsx +79 -0
  136. package/src/components/TyTextarea.tsx +154 -0
  137. package/src/components/TyTooltip.tsx +83 -0
  138. package/src/components/TyWizard.tsx +99 -0
  139. package/src/components/index.ts +251 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 gersak
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,410 @@
1
+ # tyrell-react
2
+
3
+ **React wrappers for Ty Web Components** - bringing framework-agnostic web components to React with full TypeScript support.
4
+
5
+ ## 🎯 Philosophy
6
+
7
+ Ty web components are **distributed via CDN** and loaded as standard web components. These React wrappers provide:
8
+ - ✅ **React-friendly API** - Props instead of attributes
9
+ - ✅ **TypeScript types** - Full type safety
10
+ - ✅ **Event handling** - React synthetic events
11
+ - ✅ **Ref forwarding** - Direct DOM access
12
+ - ✅ **Zero bundle overhead** - Just thin wrappers (~2KB)
13
+
14
+ ## 📦 Installation
15
+
16
+ ### Step 1: Load Ty Web Components (CDN)
17
+
18
+ Add to your `index.html`:
19
+
20
+ ```html
21
+ <!DOCTYPE html>
22
+ <html>
23
+ <head>
24
+ <!-- Ty Web Components & Styles via CDN -->
25
+ <script src="https://cdn.jsdelivr.net/npm/tyrell-components@latest/dist/tyrell.js"></script>
26
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/tyrell-components@latest/css/tyrell.css">
27
+ </head>
28
+ <body>
29
+ <div id="root"></div>
30
+ </body>
31
+ </html>
32
+ ```
33
+
34
+ ### Step 2: Install React Wrappers
35
+
36
+ ```bash
37
+ npm install tyrell-react
38
+ ```
39
+
40
+ That's it! No build complexity, no bundler configuration.
41
+
42
+ ## 🚀 Quick Start
43
+
44
+ ```tsx
45
+ import React, { useState } from 'react';
46
+ import { TyButton, TyInput, TyModal } from 'tyrell-react';
47
+
48
+ function App() {
49
+ const [value, setValue] = useState('');
50
+
51
+ return (
52
+ <div>
53
+ <TyButton flavor="primary" onClick={() => alert('Hello!')}>
54
+ Click Me
55
+ </TyButton>
56
+
57
+ <TyInput
58
+ placeholder="Enter text..."
59
+ value={value}
60
+ onChange={(e) => setValue(e.detail.value)} // Fires on every keystroke
61
+ />
62
+ </div>
63
+ );
64
+ }
65
+ ```
66
+
67
+ ## 📚 Available Components
68
+
69
+ All 18 components wrapped:
70
+
71
+ | Component | Description |
72
+ |-----------|-------------|
73
+ | `TyButton` | Semantic button with multiple flavors |
74
+ | `TyInput` | Form input with validation |
75
+ | `TyTextarea` | Multi-line text input |
76
+ | `TyCheckbox` | Checkbox with custom styling |
77
+ | `TyDropdown` | Dropdown selection |
78
+ | `TyOption` | Dropdown option |
79
+ | `TyMultiselect` | Multi-value selection |
80
+ | `TyTag` | Tag/badge component |
81
+ | `TyModal` | Modal dialogs |
82
+ | `TyPopup` | Smart popup positioning |
83
+ | `TyTooltip` | Tooltip component |
84
+ | `TyIcon` | Icon component (3000+ icons) |
85
+ | `TyCalendar` | Full calendar |
86
+ | `TyCalendarMonth` | Month view |
87
+ | `TyCalendarNavigation` | Calendar navigation |
88
+ | `TyDatePicker` | Date picker with calendar |
89
+ | `TyTabs` | Tab container |
90
+ | `TyTab` | Individual tab |
91
+ | `TyWizard` | Multi-step wizard/stepper |
92
+ | `TyStep` | Individual wizard step |
93
+ | `TyResizeObserver` | Element size observer |
94
+ | `TyScrollContainer` | Scroll wrapper with edge shadows |
95
+ | `TyCopy` | Copy-to-clipboard field |
96
+
97
+ ## ⚡ Event Handling (React Convention)
98
+
99
+ Ty React wrappers follow React conventions for event handling:
100
+
101
+ ### Input Components (Input, Textarea, Checkbox)
102
+
103
+ ```tsx
104
+ import { TyInput } from 'tyrell-react';
105
+
106
+ function SearchBox() {
107
+ const [query, setQuery] = useState('');
108
+
109
+ return (
110
+ <TyInput
111
+ value={query}
112
+ // ✅ onChange fires on every keystroke (React convention)
113
+ onChange={(e) => setQuery(e.detail.value)}
114
+
115
+ // ✅ onChangeCommit fires on blur (optional - for validation)
116
+ onChangeCommit={(e) => console.log('Final value:', e.detail.value)}
117
+ />
118
+ );
119
+ }
120
+ ```
121
+
122
+ **Key Points:**
123
+ - `onChange` → Fires on **every keystroke** (matches React's `<input onChange>`)
124
+ - `onChangeCommit` → Fires on **blur** if value changed (optional)
125
+ - This differs from native DOM where `onchange` fires on blur
126
+
127
+ ### Selection Components (Dropdown, Calendar, etc.)
128
+
129
+ ```tsx
130
+ import { TyDropdown, TyOption } from 'tyrell-react';
131
+
132
+ function CountrySelector() {
133
+ return (
134
+ <TyDropdown
135
+ // onChange fires when selection changes
136
+ onChange={(e) => console.log('Selected:', e.detail.value)}
137
+ >
138
+ <TyOption value="us">United States</TyOption>
139
+ <TyOption value="ca">Canada</TyOption>
140
+ </TyDropdown>
141
+ );
142
+ }
143
+ ```
144
+
145
+ For selection components, `onChange` fires when the selection changes (as expected).
146
+
147
+ ## 💡 Usage Examples
148
+
149
+ ### Form with Validation
150
+
151
+ ```tsx
152
+ import { TyInput, TyDropdown, TyOption, TyButton } from 'tyrell-react';
153
+
154
+ function ContactForm() {
155
+ const handleSubmit = (e: React.FormEvent) => {
156
+ e.preventDefault();
157
+ const formData = new FormData(e.currentTarget as HTMLFormElement);
158
+ console.log(Object.fromEntries(formData));
159
+ };
160
+
161
+ return (
162
+ <form onSubmit={handleSubmit}>
163
+ <TyInput
164
+ name="email"
165
+ type="email"
166
+ required
167
+ placeholder="your@email.com"
168
+ />
169
+
170
+ <TyDropdown name="role" required>
171
+ <TyOption value="admin">Administrator</TyOption>
172
+ <TyOption value="user">User</TyOption>
173
+ </TyDropdown>
174
+
175
+ <TyButton type="submit" flavor="primary">
176
+ Submit
177
+ </TyButton>
178
+ </form>
179
+ );
180
+ }
181
+ ```
182
+
183
+ ### Modal with Imperative API
184
+
185
+ ```tsx
186
+ import { useRef } from 'react';
187
+ import { TyModal, TyButton, type TyModalRef } from 'tyrell-react';
188
+
189
+ function ModalExample() {
190
+ const modalRef = useRef<TyModalRef>(null);
191
+
192
+ return (
193
+ <>
194
+ <TyButton onClick={() => modalRef.current?.show()}>
195
+ Open Modal
196
+ </TyButton>
197
+
198
+ <TyModal
199
+ ref={modalRef}
200
+ onClose={(e) => console.log('Closed:', e.detail.reason)}
201
+ >
202
+ <h2>Modal Content</h2>
203
+ <TyButton onClick={() => modalRef.current?.hide()}>
204
+ Close
205
+ </TyButton>
206
+ </TyModal>
207
+ </>
208
+ );
209
+ }
210
+ ```
211
+
212
+ ### Calendar with Custom Rendering
213
+
214
+ ```tsx
215
+ import { useState } from 'react';
216
+ import { TyCalendar } from 'tyrell-react';
217
+
218
+ function CalendarExample() {
219
+ const [selected, setSelected] = useState<Date | null>(null);
220
+
221
+ return (
222
+ <TyCalendar
223
+ value={selected?.getTime()}
224
+ onChange={(e) => setSelected(new Date(e.detail.date))}
225
+ min="2024-01-01"
226
+ max="2024-12-31"
227
+ />
228
+ );
229
+ }
230
+ ```
231
+
232
+ ## 🪟 Surfaces
233
+
234
+ The Tyrell design system has five surface levels (background + shadow). They ship as
235
+ CSS utility classes — apply them directly to any element. There is no wrapper component
236
+ to learn:
237
+
238
+ ```tsx
239
+ function Dashboard() {
240
+ return (
241
+ <section className="ty-elevated p-6 rounded-lg">
242
+ <h2>Card title</h2>
243
+ <p>Sits above the page background.</p>
244
+ </section>
245
+ );
246
+ }
247
+ ```
248
+
249
+ | Class | Use for |
250
+ |----------------|--------------------------------------|
251
+ | `ty-floating` | modals, dropdowns, tooltips |
252
+ | `ty-elevated` | cards, panels, sidebars |
253
+ | `ty-content` | main content areas |
254
+ | `ty-canvas` | app/page background |
255
+ | `ty-input` | form control surface |
256
+
257
+ **Golden rule:** use Tyrell surface/colour classes for colour, Tailwind (or your own utilities)
258
+ for everything else (spacing, layout, typography). Don't mix `bg-blue-500` with surfaces.
259
+
260
+ ## 🎨 Icons (3000+ Available)
261
+
262
+ Import only the icons you need (tree-shaking) and register them once at app startup
263
+ via the global `window.tyIcons` API exposed by `tyrell-components`:
264
+
265
+ ```tsx
266
+ // app/icons.ts (or wherever your app boots)
267
+ import { check, heart, star } from 'tyrell-components/icons/lucide';
268
+
269
+ export function registerIcons() {
270
+ window.tyIcons.register({ check, heart, star });
271
+ }
272
+ ```
273
+
274
+ ```tsx
275
+ // app/layout.tsx (call once, e.g. in a top-level effect)
276
+ 'use client';
277
+ import { useEffect } from 'react';
278
+ import { registerIcons } from './icons';
279
+
280
+ export default function RootLayout({ children }) {
281
+ useEffect(() => { registerIcons(); }, []);
282
+ return <>{children}</>;
283
+ }
284
+ ```
285
+
286
+ Then use icons anywhere in React:
287
+
288
+ ```tsx
289
+ import { TyIcon, TyButton } from 'tyrell-react';
290
+
291
+ function IconExample() {
292
+ return (
293
+ <>
294
+ <TyIcon name="check" size="lg" />
295
+
296
+ <TyButton flavor="primary">
297
+ <TyIcon name="heart" />
298
+ Like
299
+ </TyButton>
300
+ </>
301
+ );
302
+ }
303
+ ```
304
+
305
+ CDN alternative (vanilla HTML, no bundler):
306
+
307
+ ```html
308
+ <script type="module">
309
+ import { check, heart, star }
310
+ from 'https://cdn.jsdelivr.net/npm/tyrell-components@latest/lib/icons/lucide.js';
311
+
312
+ window.tyIcons.register({ check, heart, star });
313
+ </script>
314
+ ```
315
+
316
+ ## 📘 TypeScript Support
317
+
318
+ Full TypeScript definitions included:
319
+
320
+ ```tsx
321
+ import type {
322
+ TyButtonProps,
323
+ TyInputEventDetail,
324
+ TyModalRef,
325
+ TyDropdownEventDetail
326
+ } from 'tyrell-react';
327
+
328
+ // Type-safe props
329
+ const buttonProps: TyButtonProps = {
330
+ flavor: 'primary', // ✅ Autocomplete
331
+ size: 'lg', // ✅ Type-checked
332
+ disabled: false
333
+ };
334
+
335
+ // Type-safe event handlers
336
+ const handleChange = (e: CustomEvent<TyInputEventDetail>) => {
337
+ console.log(e.detail.value); // ✅ Typed
338
+ console.log(e.detail.rawValue); // ✅ Typed
339
+ };
340
+ ```
341
+
342
+ ## 🌐 ClojureScript Support
343
+
344
+ Works perfectly with Reagent and UIx:
345
+
346
+ ### Reagent
347
+
348
+ ```clojure
349
+ (ns my-app.core
350
+ (:require ["tyrell-react" :as ty]))
351
+
352
+ (defn my-component []
353
+ [:div
354
+ [:> ty/TyButton {:flavor "primary"} "Click Me"]
355
+ [:> ty/TyInput {:placeholder "Enter text..."}]])
356
+ ```
357
+
358
+ ### UIx
359
+
360
+ ```clojure
361
+ (ns my-app.core
362
+ (:require [uix.core :as uix]
363
+ ["tyrell-react" :refer [TyButton TyInput]]))
364
+
365
+ (defn my-component []
366
+ (uix/view
367
+ [:<>
368
+ [TyButton {:flavor "primary"} "Click Me"]
369
+ [TyInput {:placeholder "Enter text..."}]]))
370
+ ```
371
+
372
+ ## 🔧 Peer Dependencies
373
+
374
+ Only React is required:
375
+ - `react` >=18.0.0
376
+ - `react-dom` >=18.0.0
377
+
378
+ **Note:** The core `tyrell-components` web components are loaded via CDN, not as an npm dependency!
379
+
380
+ ## 🌍 Browser Support
381
+
382
+ Modern browsers with Web Components support:
383
+ - Chrome 67+
384
+ - Firefox 63+
385
+ - Safari 13.1+
386
+ - Edge 79+
387
+
388
+ ## 📝 Why CDN Distribution?
389
+
390
+ **Ty web components are framework-agnostic** and designed for CDN distribution:
391
+
392
+ ✅ **Zero version conflicts** - One version serves all frameworks
393
+ ✅ **Smaller bundles** - Web components load once, shared across all React components
394
+ ✅ **No build complexity** - Just script tags
395
+ ✅ **Better caching** - CDN edge network
396
+ ✅ **Framework freedom** - Same components work in React, Vue, Svelte, vanilla JS
397
+
398
+ ## 🤝 Contributing
399
+
400
+ This package is part of the [Ty monorepo](https://github.com/gersak/tyrell).
401
+
402
+ ## 📄 License
403
+
404
+ MIT License - see [LICENSE](./LICENSE)
405
+
406
+ ## 🔗 Links
407
+
408
+ - [Ty Core Package](https://www.npmjs.com/package/tyrell-components)
409
+ - [GitHub Repository](https://github.com/gersak/tyrell)
410
+ - [Documentation](https://tyrell.gersak.dev) (Coming Soon)
@@ -0,0 +1,50 @@
1
+ import React from 'react';
2
+ type BuiltinFlavor = 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'neutral';
3
+ type ShadedFlavor = BuiltinFlavor | `${BuiltinFlavor}+` | `${BuiltinFlavor}-`;
4
+ type ButtonAppearance = 'solid' | 'outlined' | 'ghost';
5
+ export interface TyButtonCSSProperties extends React.CSSProperties {
6
+ '--ty-button-bg'?: string;
7
+ '--ty-button-bg-hover'?: string;
8
+ '--ty-button-color'?: string;
9
+ '--ty-button-border'?: string;
10
+ }
11
+ export interface TyButtonProps extends Omit<React.HTMLAttributes<HTMLElement>, 'style'> {
12
+ style?: TyButtonCSSProperties;
13
+ /**
14
+ * Semantic styling variant. Built-in flavors get themed styles; append `+`
15
+ * for a stronger shade or `-` for a softer one (e.g. `"primary+"`,
16
+ * `"danger-"`). Any other string is passed through as-is — theme it via
17
+ * `--ty-button-*` CSS variables.
18
+ */
19
+ flavor?: ShadedFlavor | (string & {});
20
+ /**
21
+ * Visual appearance:
22
+ * - `"solid"` (default) — saturated brand fill with paired text color
23
+ * - `"outlined"` — transparent background, text === border
24
+ * - `"ghost"` — text only with hover background
25
+ */
26
+ appearance?: ButtonAppearance;
27
+ /** Button size */
28
+ size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
29
+ /** Button type for form submission */
30
+ type?: 'button' | 'submit' | 'reset';
31
+ /** Disable the button */
32
+ disabled?: boolean;
33
+ /** Pill-shaped button (rounded ends) */
34
+ pill?: boolean;
35
+ /** Action (icon-only square) */
36
+ action?: boolean;
37
+ /** Accessible label for screen readers */
38
+ label?: string;
39
+ /** Form field name for form submission */
40
+ name?: string;
41
+ /** Form field value for form submission */
42
+ value?: string;
43
+ /** Full-width button */
44
+ wide?: boolean;
45
+ /** Button content */
46
+ children?: React.ReactNode;
47
+ }
48
+ export declare const TyButton: React.ForwardRefExoticComponent<TyButtonProps & React.RefAttributes<HTMLElement>>;
49
+ export {};
50
+ //# sourceMappingURL=TyButton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TyButton.d.ts","sourceRoot":"","sources":["../../src/components/TyButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyC,MAAM,OAAO,CAAC;AAE9D,KAAK,aAAa,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;AAC5F,KAAK,YAAY,GAAG,aAAa,GAAG,GAAG,aAAa,GAAG,GAAG,GAAG,aAAa,GAAG,CAAC;AAC9E,KAAK,gBAAgB,GAAG,OAAO,GAAG,UAAU,GAAG,OAAO,CAAC;AAEvD,MAAM,WAAW,qBAAsB,SAAQ,KAAK,CAAC,aAAa;IAChE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IACrF,KAAK,CAAC,EAAE,qBAAqB,CAAC;IAC9B;;;;;OAKG;IACH,MAAM,CAAC,EAAE,YAAY,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IAEtC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAE9B,kBAAkB;IAClB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAExC,sCAAsC;IACtC,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC;IAErC,yBAAyB;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,wCAAwC;IACxC,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf,gCAAgC;IAChC,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB,0CAA0C;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,2CAA2C;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,wBAAwB;IACxB,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf,qBAAqB;IACrB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED,eAAO,MAAM,QAAQ,mFAgFpB,CAAC"}
@@ -0,0 +1,68 @@
1
+ import React, { useEffect, useRef } from 'react';
2
+ export const TyButton = React.forwardRef(({ children, type, appearance, disabled, pill, action, wide, label, name, value, onClick, ...props }, ref) => {
3
+ const elementRef = useRef(null);
4
+ // Imperatively attach the click listener so onClick reliably fires for the
5
+ // CustomEvent('click') that <ty-button> re-dispatches on its host (the
6
+ // inner <button> calls stopPropagation, so React's delegated onClick can
7
+ // miss it). Also handles type=submit by dispatching a synthetic submit.
8
+ useEffect(() => {
9
+ const element = elementRef.current;
10
+ if (!element)
11
+ return;
12
+ const handler = (event) => {
13
+ if (type === 'submit') {
14
+ const form = element.closest('form');
15
+ if (form) {
16
+ event.preventDefault();
17
+ event.stopPropagation();
18
+ form.dispatchEvent(new Event('submit', {
19
+ bubbles: true,
20
+ cancelable: true,
21
+ }));
22
+ }
23
+ }
24
+ if (onClick) {
25
+ onClick(event);
26
+ }
27
+ };
28
+ element.addEventListener('click', handler);
29
+ return () => {
30
+ element.removeEventListener('click', handler);
31
+ };
32
+ }, [type, onClick]);
33
+ useEffect(() => {
34
+ if (ref && elementRef.current) {
35
+ if (typeof ref === 'function') {
36
+ ref(elementRef.current);
37
+ }
38
+ else {
39
+ ref.current = elementRef.current;
40
+ }
41
+ }
42
+ }, [ref]);
43
+ const webComponentProps = {
44
+ ...props,
45
+ ref: elementRef,
46
+ };
47
+ if (disabled)
48
+ webComponentProps.disabled = '';
49
+ if (pill)
50
+ webComponentProps.pill = '';
51
+ if (action)
52
+ webComponentProps.action = '';
53
+ if (wide)
54
+ webComponentProps.wide = '';
55
+ if (appearance)
56
+ webComponentProps.appearance = appearance;
57
+ if (type)
58
+ webComponentProps.type = type;
59
+ if (label)
60
+ webComponentProps.label = label;
61
+ if (name)
62
+ webComponentProps.name = name;
63
+ if (value)
64
+ webComponentProps.value = value;
65
+ return React.createElement('ty-button', webComponentProps, children);
66
+ });
67
+ TyButton.displayName = 'TyButton';
68
+ //# sourceMappingURL=TyButton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TyButton.js","sourceRoot":"","sources":["../../src/components/TyButton.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ import React from 'react';
2
+ export interface TyCalendarChangeEventDetail {
3
+ /** Selected month (1-12) */
4
+ month: number;
5
+ /** Selected year (4-digit) */
6
+ year: number;
7
+ /** Selected day (1-31) */
8
+ day: number;
9
+ /** Action that triggered the change: "select" */
10
+ action: 'select';
11
+ /** Source of the change: "day-click" */
12
+ source: 'day-click';
13
+ /** Complete day context from the calendar month */
14
+ dayContext: any;
15
+ }
16
+ export interface TyCalendarNavigateEventDetail {
17
+ /** Navigation target month (1-12) */
18
+ month: number;
19
+ /** Navigation target year (4-digit) */
20
+ year: number;
21
+ /** Action that triggered the navigation: "navigate" */
22
+ action: 'navigate';
23
+ /** Source of the change: "navigation" */
24
+ source: 'navigation';
25
+ }
26
+ export interface TyCalendarProps extends Omit<React.HTMLAttributes<HTMLElement>, 'onChange'> {
27
+ /** Selected year (4-digit) */
28
+ year?: number | string;
29
+ /** Selected month (1-12) */
30
+ month?: number | string;
31
+ /** Selected day (1-31) */
32
+ day?: number | string;
33
+ /** Show navigation controls */
34
+ showNavigation?: boolean;
35
+ /** Stateless mode - no internal state management */
36
+ stateless?: boolean;
37
+ /** Calendar size */
38
+ size?: 'sm' | 'md' | 'lg';
39
+ /** Locale for date formatting */
40
+ locale?: string;
41
+ /** Calendar width */
42
+ width?: string | number;
43
+ /** Minimum calendar width */
44
+ minWidth?: string | number;
45
+ /** Maximum calendar width */
46
+ maxWidth?: string | number;
47
+ /** Form field name for form submission */
48
+ name?: string;
49
+ /** Form value (ISO date string) */
50
+ value?: string;
51
+ /** Function to render custom day content */
52
+ dayContentFn?: (dayContext: any) => HTMLElement | string;
53
+ /** Function to determine day CSS classes */
54
+ dayClassesFn?: (dayContext: any) => string[];
55
+ /** Custom CSS injection for render functions */
56
+ customCSS?: string;
57
+ /** Callback when a date is selected */
58
+ onChange?: (event: CustomEvent<TyCalendarChangeEventDetail>) => void;
59
+ /** Callback when navigation changes month/year */
60
+ onNavigate?: (event: CustomEvent<TyCalendarNavigateEventDetail>) => void;
61
+ }
62
+ export declare const TyCalendar: React.ForwardRefExoticComponent<TyCalendarProps & React.RefAttributes<HTMLElement>>;
63
+ //# sourceMappingURL=TyCalendar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TyCalendar.d.ts","sourceRoot":"","sources":["../../src/components/TyCalendar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyC,MAAM,OAAO,CAAC;AAG9D,MAAM,WAAW,2BAA2B;IAC1C,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,iDAAiD;IACjD,MAAM,EAAE,QAAQ,CAAC;IACjB,wCAAwC;IACxC,MAAM,EAAE,WAAW,CAAC;IACpB,mDAAmD;IACnD,UAAU,EAAE,GAAG,CAAC;CACjB;AAED,MAAM,WAAW,6BAA6B;IAC5C,qCAAqC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,MAAM,EAAE,UAAU,CAAC;IACnB,yCAAyC;IACzC,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,UAAU,CAAC;IAC1F,8BAA8B;IAC9B,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAEvB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAExB,0BAA0B;IAC1B,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAEtB,+BAA+B;IAC/B,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB,oDAAoD;IACpD,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,oBAAoB;IACpB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAE1B,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,qBAAqB;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAExB,6BAA6B;IAC7B,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAE3B,6BAA6B;IAC7B,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAE3B,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,mCAAmC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,4CAA4C;IAC5C,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,GAAG,KAAK,WAAW,GAAG,MAAM,CAAC;IAEzD,4CAA4C;IAC5C,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,GAAG,KAAK,MAAM,EAAE,CAAC;IAE7C,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,uCAAuC;IACvC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,2BAA2B,CAAC,KAAK,IAAI,CAAC;IAErE,kDAAkD;IAClD,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,6BAA6B,CAAC,KAAK,IAAI,CAAC;CAC1E;AAGD,eAAO,MAAM,UAAU,qFA8JtB,CAAC"}