tyrell-components 1.0.0-TC23 → 1.0.0-TC25

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 (59) hide show
  1. package/css/tyrell-brand.css +176 -78
  2. package/css/tyrell-simple.css +257 -0
  3. package/css/tyrell.css +34 -20
  4. package/dist/tyrell-brand.css +176 -78
  5. package/dist/tyrell.css +34 -20
  6. package/dist/tyrell.js +1 -1
  7. package/lib/base/ty-component.d.ts +7 -0
  8. package/lib/base/ty-component.d.ts.map +1 -1
  9. package/lib/base/ty-component.js +27 -0
  10. package/lib/base/ty-component.js.map +1 -1
  11. package/lib/components/checkbox.d.ts +2 -0
  12. package/lib/components/checkbox.d.ts.map +1 -1
  13. package/lib/components/checkbox.js +20 -0
  14. package/lib/components/checkbox.js.map +1 -1
  15. package/lib/components/input.d.ts +8 -0
  16. package/lib/components/input.d.ts.map +1 -1
  17. package/lib/components/input.js +50 -4
  18. package/lib/components/input.js.map +1 -1
  19. package/lib/components/radio.d.ts.map +1 -1
  20. package/lib/components/radio.js +2 -0
  21. package/lib/components/radio.js.map +1 -1
  22. package/lib/components/scroll-container.d.ts +16 -0
  23. package/lib/components/scroll-container.d.ts.map +1 -1
  24. package/lib/components/scroll-container.js +105 -1
  25. package/lib/components/scroll-container.js.map +1 -1
  26. package/lib/components/switch.d.ts +2 -0
  27. package/lib/components/switch.d.ts.map +1 -1
  28. package/lib/components/switch.js +18 -0
  29. package/lib/components/switch.js.map +1 -1
  30. package/lib/components/textarea.d.ts +3 -0
  31. package/lib/components/textarea.d.ts.map +1 -1
  32. package/lib/components/textarea.js +61 -6
  33. package/lib/components/textarea.js.map +1 -1
  34. package/lib/styles/button.d.ts +5 -2
  35. package/lib/styles/button.d.ts.map +1 -1
  36. package/lib/styles/button.js +35 -71
  37. package/lib/styles/button.js.map +1 -1
  38. package/lib/styles/calendar-month.d.ts +1 -1
  39. package/lib/styles/calendar-month.d.ts.map +1 -1
  40. package/lib/styles/calendar-month.js +26 -58
  41. package/lib/styles/calendar-month.js.map +1 -1
  42. package/lib/styles/calendar-navigation.d.ts +1 -1
  43. package/lib/styles/calendar-navigation.d.ts.map +1 -1
  44. package/lib/styles/calendar-navigation.js +10 -32
  45. package/lib/styles/calendar-navigation.js.map +1 -1
  46. package/lib/styles/scroll-container.d.ts +1 -1
  47. package/lib/styles/scroll-container.d.ts.map +1 -1
  48. package/lib/styles/scroll-container.js +6 -0
  49. package/lib/styles/scroll-container.js.map +1 -1
  50. package/lib/styles/tag.d.ts +1 -1
  51. package/lib/styles/tag.d.ts.map +1 -1
  52. package/lib/styles/tag.js +5 -5
  53. package/lib/styles/textarea.d.ts +1 -1
  54. package/lib/styles/textarea.d.ts.map +1 -1
  55. package/lib/styles/textarea.js +67 -33
  56. package/lib/styles/textarea.js.map +1 -1
  57. package/lib/version.d.ts +1 -1
  58. package/lib/version.js +1 -1
  59. package/package.json +10 -2
package/lib/styles/tag.js CHANGED
@@ -194,7 +194,7 @@ export const tagStyles = `
194
194
  /* ----- PRIMARY ----- */
195
195
  :host([flavor="primary"]) {
196
196
  --tag-bg: var(--ty-bg-primary);
197
- --tag-color: var(--ty-color-primary-strong);
197
+ --tag-color: var(--ty-color-primary);
198
198
  --tag-border-color: var(--ty-border-primary);
199
199
  }
200
200
  :host([flavor="primary+"]) {
@@ -221,7 +221,7 @@ export const tagStyles = `
221
221
  /* ----- SECONDARY ----- */
222
222
  :host([flavor="secondary"]) {
223
223
  --tag-bg: var(--ty-bg-secondary);
224
- --tag-color: var(--ty-color-secondary-strong);
224
+ --tag-color: var(--ty-color-secondary);
225
225
  --tag-border-color: var(--ty-border-secondary);
226
226
  }
227
227
  :host([flavor="secondary+"]) {
@@ -248,7 +248,7 @@ export const tagStyles = `
248
248
  /* ----- SUCCESS ----- */
249
249
  :host([flavor="success"]) {
250
250
  --tag-bg: var(--ty-bg-success);
251
- --tag-color: var(--ty-color-success-strong);
251
+ --tag-color: var(--ty-color-success);
252
252
  --tag-border-color: var(--ty-border-success);
253
253
  }
254
254
  :host([flavor="success+"]) {
@@ -275,7 +275,7 @@ export const tagStyles = `
275
275
  /* ----- DANGER ----- */
276
276
  :host([flavor="danger"]) {
277
277
  --tag-bg: var(--ty-bg-danger);
278
- --tag-color: var(--ty-color-danger-strong);
278
+ --tag-color: var(--ty-color-danger);
279
279
  --tag-border-color: var(--ty-border-danger);
280
280
  }
281
281
  :host([flavor="danger+"]) {
@@ -302,7 +302,7 @@ export const tagStyles = `
302
302
  /* ----- WARNING ----- */
303
303
  :host([flavor="warning"]) {
304
304
  --tag-bg: var(--ty-bg-warning);
305
- --tag-color: var(--ty-color-warning-strong);
305
+ --tag-color: var(--ty-color-warning);
306
306
  --tag-border-color: var(--ty-border-warning);
307
307
  }
308
308
  :host([flavor="warning+"]) {
@@ -2,5 +2,5 @@
2
2
  * Styles for ty-textarea component
3
3
  * Enhanced textarea with auto-resize functionality
4
4
  */
5
- export declare const textareaStyles = "\n:host {\n display: block;\n font-family: var(--ty-font-sans);\n width: 100%;\n}\n\n.textarea-container {\n display: flex;\n flex-direction: column;\n width: 100%;\n box-sizing: border-box;\n position: relative;\n /* For absolute positioned dummy element */\n}\n\n.textarea-wrapper {\n position: relative;\n width: 100%;\n}\n\n/* Custom scrollbar track positioning within textarea border */\n.textarea-wrapper .ty-scrollbar-track-y {\n top: 2px;\n right: 2px;\n bottom: 2px;\n border-radius: 0 4px 4px 0;\n}\n\n/* ===== LABEL STYLING ===== */\n\n.ty-field-label {\n font-size: var(--ty-font-sm);\n line-height: var(--ty-leading-sm);\n letter-spacing: var(--ty-tracking-sm);\n font-weight: var(--ty-font-medium);\n color: var(--ty-label-color);\n margin-bottom: 6px;\n padding-left: 12px;\n}\n\n/* Required indicator - using SVG icon instead of CSS */\n.required-icon {\n display: inline-flex;\n align-items: center;\n color: var(--ty-color-danger);\n width: 12px;\n height: 12px;\n vertical-align: middle;\n}\n\n/* ===== ERROR MESSAGE STYLING ===== */\n\n.error-message {\n font-size: var(--ty-font-xs);\n line-height: var(--ty-leading-xs);\n letter-spacing: var(--ty-tracking-xs);\n color: var(--ty-color-danger);\n margin-top: 4px;\n padding-left: 12px;\n}\n\n/* Error state for textareas */\ntextarea.error {\n border-color: var(--ty-color-danger);\n background: var(--ty-bg-danger-soft);\n}\n\ntextarea.error:focus {\n border-color: var(--ty-color-danger-bold);\n box-shadow: 0 0 0 3px var(--input-shadow-focus, var(--ty-input-shadow-focus));\n}\n\n/* ===== TEXTAREA BASE STYLING ===== */\n\ntextarea {\n /* Base appearance \u2014 elegant and minimal like input */\n box-sizing: border-box;\n width: 100%;\n border: 1px solid var(--input-border, var(--ty-input-border));\n border-radius: 6px;\n background: var(--input-bg, var(--ty-input-bg));\n color: var(--input-color, var(--ty-input-color));\n font-family: inherit;\n /* Linear-paired typography */\n font-size: var(--ty-font-sm);\n line-height: var(--ty-leading-sm);\n letter-spacing: var(--ty-tracking-sm);\n font-weight: var(--ty-font-normal);\n transition: all 0.15s ease-in-out;\n outline: none;\n\n /* Default size (md) - refined spacing */\n min-height: 80px;\n /* Larger than input for multiline */\n padding: 12px 12px;\n /* Slightly larger padding for text areas */\n\n /* Auto-resize specific styles */\n overflow: hidden;\n /* Hide scrollbars since we're auto-resizing */\n resize: none;\n /* Disable manual resize by default */\n\n /* Ensure consistent text wrapping */\n white-space: pre-wrap;\n word-wrap: break-word;\n}\n\n/* Hide native scrollbar for webkit when custom scrollbar is active\n (scrollbar-width: none handles Firefox; this handles Chrome/Safari) */\n:host([data-custom-scroll]) textarea::-webkit-scrollbar {\n display: none;\n}\n\n/* Focus state - elegant blue glow like input */\ntextarea:focus {\n border-color: var(--input-border-focus, var(--ty-input-border-focus));\n box-shadow: 0 0 0 3px var(--input-shadow-focus, var(--ty-input-shadow-focus));\n background: var(--input-bg, var(--ty-input-bg));\n}\n\n/* Hover state - subtle feedback */\ntextarea:hover:not(:disabled) {\n border-color: var(--input-border-hover, var(--ty-input-border-hover));\n}\n\n/* Disabled state - refined opacity */\ntextarea:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n background: var(--input-disabled-bg, var(--ty-input-disabled-bg));\n border-color: var(--input-disabled-border, var(--ty-input-disabled-border));\n color: var(--input-disabled-color, var(--ty-input-disabled-color));\n}\n\n/* Placeholder styling - subtle and elegant */\ntextarea::placeholder {\n color: var(--input-placeholder, var(--ty-input-placeholder));\n font-weight: 400;\n}\n\n/* ===== RESIZE CONTROL OPTIONS ===== */\n\n/* Allow manual resizing */\ntextarea.resize-both {\n resize: both;\n}\n\ntextarea.resize-horizontal {\n resize: horizontal;\n}\n\ntextarea.resize-vertical {\n resize: vertical;\n}\n\ntextarea.resize-none {\n resize: none;\n}\n\n/* Auto-resize mode (default) disables manual resize */\ntextarea:not(.resize-both):not(.resize-horizontal):not(.resize-vertical) {\n resize: none;\n}\n\n/* ===== DUMMY ELEMENT FOR AUTO-RESIZE ===== */\n\n.textarea-dummy {\n /* Hidden element that measures text height */\n position: absolute !important;\n top: 0 !important;\n left: 0 !important;\n visibility: hidden !important;\n white-space: pre-wrap !important;\n word-break: break-word !important;\n box-sizing: border-box !important;\n overflow: hidden !important;\n pointer-events: none !important;\n z-index: -1 !important;\n\n /* Ensure it has the same text behavior as textarea */\n word-wrap: break-word !important;\n overflow-wrap: break-word !important;\n}\n\n/* ===== SIZE MODIFIERS ===== */\n\n/* Extra Small */\ntextarea.xs {\n min-height: 64px;\n padding: 8px 10px;\n font-size: var(--ty-font-xs);\n line-height: var(--ty-leading-xs);\n letter-spacing: var(--ty-tracking-xs);\n}\n\n/* Small */\ntextarea.sm {\n min-height: 72px;\n padding: 10px 10px;\n font-size: var(--ty-font-sm);\n line-height: var(--ty-leading-sm);\n letter-spacing: var(--ty-tracking-sm);\n}\n\n/* Medium (default) */\ntextarea.md {\n min-height: 80px;\n padding: 12px 12px;\n font-size: var(--ty-font-sm);\n line-height: var(--ty-leading-sm);\n letter-spacing: var(--ty-tracking-sm);\n}\n\n/* Large */\ntextarea.lg {\n min-height: 96px;\n padding: 14px 14px;\n font-size: var(--ty-font-base);\n line-height: var(--ty-leading-base);\n letter-spacing: var(--ty-tracking-base);\n}\n\n/* Extra Large */\ntextarea.xl {\n min-height: 112px;\n padding: 16px 16px;\n font-size: var(--ty-font-lg);\n line-height: var(--ty-leading-lg);\n letter-spacing: var(--ty-tracking-lg);\n}\n\n/* ===== ACCESSIBILITY ENHANCEMENTS ===== */\n\ntextarea:focus-visible {\n outline: none;\n /* We use box-shadow instead */\n}\n\n/* High contrast mode support */\n@media (prefers-contrast: high) {\n textarea {\n border-width: 2px;\n }\n}\n\n/* Reduced motion support */\n@media (prefers-reduced-motion: reduce) {\n textarea {\n transition: none;\n }\n\n .textarea-dummy {\n transition: none;\n }\n}\n\n/* ===== CONTAINER-AWARE RESPONSIVE BEHAVIOR ===== */\n\n/* Scale down on smaller containers using container queries */\n@container (max-width: 480px) {\n textarea.lg {\n font-size: var(--ty-font-sm);\n line-height: var(--ty-leading-sm);\n letter-spacing: var(--ty-tracking-sm);\n padding: 12px 12px;\n min-height: 80px;\n }\n\n textarea.xl {\n font-size: var(--ty-font-base);\n line-height: var(--ty-leading-base);\n letter-spacing: var(--ty-tracking-base);\n padding: 14px 14px;\n min-height: 96px;\n }\n}\n\n@container (max-width: 320px) {\n textarea.xl {\n font-size: var(--ty-font-sm);\n line-height: var(--ty-leading-sm);\n letter-spacing: var(--ty-tracking-sm);\n padding: 12px 12px;\n min-height: 80px;\n }\n}\n\n/* Fallback for browsers without container query support */\n@media (max-width: 640px) {\n textarea.lg {\n font-size: var(--ty-font-sm);\n line-height: var(--ty-leading-sm);\n letter-spacing: var(--ty-tracking-sm);\n padding: 12px 12px;\n min-height: 80px;\n }\n\n textarea.xl {\n font-size: var(--ty-font-base);\n line-height: var(--ty-leading-base);\n letter-spacing: var(--ty-tracking-base);\n padding: 14px 14px;\n min-height: 96px;\n }\n}\n\n@media (max-width: 480px) {\n textarea.xl {\n font-size: var(--ty-font-sm);\n line-height: var(--ty-leading-sm);\n letter-spacing: var(--ty-tracking-sm);\n padding: 12px 12px;\n min-height: 80px;\n }\n}\n\n/* ===== ANIMATION AND TRANSITIONS ===== */\n\n/* Smooth height transitions for auto-resize */\ntextarea {\n transition:\n border-color 0.15s ease-in-out,\n box-shadow 0.15s ease-in-out,\n background-color 0.15s ease-in-out,\n height 0.1s ease-out;\n /* Smooth height changes */\n}\n\n/* Disable height transition on focus to avoid jarring effect */\ntextarea:focus {\n transition:\n border-color 0.15s ease-in-out,\n box-shadow 0.15s ease-in-out,\n background-color 0.15s ease-in-out;\n}\n\n/* For users who prefer reduced motion, disable height transitions */\n@media (prefers-reduced-motion: reduce) {\n textarea {\n transition: none;\n }\n}\n";
5
+ export declare const textareaStyles = "\n:host {\n display: block;\n font-family: var(--ty-font-sans);\n width: 100%;\n}\n\n.textarea-container {\n display: flex;\n flex-direction: column;\n width: 100%;\n box-sizing: border-box;\n position: relative;\n /* For absolute positioned dummy element */\n}\n\n/* Bordered container \u2014 owns the border + active state (composer layout):\n header (top slot) \u00B7 textarea (borderless) \u00B7 footer (bottom slot). */\n.textarea-wrapper {\n position: relative;\n width: 100%;\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n border: 1px solid var(--input-border, var(--ty-input-border));\n border-radius: 6px;\n background: var(--input-bg, var(--ty-input-bg));\n transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n\n/* Active ring tied to the TEXTAREA specifically (not :focus-within) so tabbing\n to a footer button doesn't make the whole field look focused. */\n.textarea-wrapper:has(textarea:focus) {\n border-color: var(--input-border-focus, var(--ty-input-border-focus));\n box-shadow: 0 0 0 3px var(--input-shadow-focus, var(--ty-input-shadow-focus));\n}\n\n/* Error + disabled reflected from the inner textarea (both in shadow DOM, so\n :has is reliable here \u2014 unlike slotted content). */\n.textarea-wrapper:has(textarea.error) {\n border-color: var(--ty-color-danger);\n background: var(--ty-bg-danger-soft);\n}\n.textarea-wrapper:has(textarea.error):has(textarea:focus) {\n border-color: var(--ty-color-danger-bold);\n}\n.textarea-wrapper:has(textarea:disabled) {\n opacity: 0.5;\n background: var(--input-disabled-bg, var(--ty-input-disabled-bg));\n border-color: var(--input-disabled-border, var(--ty-input-disabled-border));\n}\n\n/* Scroll region wraps just the textarea so the custom scrollbar never overlaps\n the header/footer. */\n.textarea-scroll {\n position: relative;\n flex: 1 1 auto;\n min-height: 0;\n display: flex;\n}\n\n/* Custom scrollbar track positioned to the scroll region (textarea edges) */\n.textarea-scroll .ty-scrollbar-track-y {\n top: 2px;\n right: 2px;\n bottom: 2px;\n border-radius: 0 4px 4px 0;\n}\n\n/* Header / footer slot regions \u2014 zero footprint until they have content\n (the component toggles .has-content via slotchange). footer defaults to\n space-between so \"tools \u2026 submit\" works; a single wide button fills it. */\n.textarea-header,\n.textarea-footer {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n.textarea-footer { justify-content: space-between; }\n.textarea-header.has-content {\n padding: 6px 10px;\n border-bottom: 1px solid var(--ty-textarea-divider, var(--input-border, var(--ty-input-border)));\n}\n.textarea-footer.has-content {\n padding: 6px 10px;\n border-top: 1px solid var(--ty-textarea-divider, var(--input-border, var(--ty-input-border)));\n}\n\n/* ===== LABEL STYLING ===== */\n\n.ty-field-label {\n font-size: var(--ty-font-sm);\n line-height: var(--ty-leading-sm);\n letter-spacing: var(--ty-tracking-sm);\n font-weight: var(--ty-font-medium);\n color: var(--ty-label-color);\n margin-bottom: 6px;\n padding-left: 12px;\n}\n\n/* Required indicator - using SVG icon instead of CSS */\n.required-icon {\n display: inline-flex;\n align-items: center;\n color: var(--ty-color-danger);\n width: 12px;\n height: 12px;\n vertical-align: middle;\n}\n\n/* ===== ERROR MESSAGE STYLING ===== */\n\n.error-message {\n font-size: var(--ty-font-xs);\n line-height: var(--ty-leading-xs);\n letter-spacing: var(--ty-tracking-xs);\n color: var(--ty-color-danger);\n margin-top: 4px;\n padding-left: 12px;\n}\n\n/* Error state is reflected on .textarea-wrapper (see above). */\n\n/* ===== TEXTAREA BASE STYLING ===== */\n\ntextarea {\n /* Borderless \u2014 the .textarea-wrapper owns the border/background now. */\n box-sizing: border-box;\n width: 100%;\n flex: 1 1 auto;\n border: none;\n background: transparent;\n color: var(--input-color, var(--ty-input-color));\n font-family: inherit;\n /* Linear-paired typography */\n font-size: var(--ty-font-sm);\n line-height: var(--ty-leading-sm);\n letter-spacing: var(--ty-tracking-sm);\n font-weight: var(--ty-font-normal);\n outline: none;\n\n /* Default size (md) - refined spacing */\n min-height: 80px;\n /* Larger than input for multiline */\n padding: 12px 12px;\n /* Slightly larger padding for text areas */\n\n /* Auto-resize specific styles */\n overflow: hidden;\n /* Hide scrollbars since we're auto-resizing */\n resize: none;\n /* Disable manual resize by default */\n\n /* Ensure consistent text wrapping */\n white-space: pre-wrap;\n word-wrap: break-word;\n}\n\n/* Hide native scrollbar for webkit when custom scrollbar is active\n (scrollbar-width: none handles Firefox; this handles Chrome/Safari) */\n:host([data-custom-scroll]) textarea::-webkit-scrollbar {\n display: none;\n}\n\n/* Disabled \u2014 visual state lives on the wrapper; just the cursor/text here. */\ntextarea:disabled {\n cursor: not-allowed;\n color: var(--input-disabled-color, var(--ty-input-disabled-color));\n}\n\n/* Placeholder styling - subtle and elegant */\ntextarea::placeholder {\n color: var(--input-placeholder, var(--ty-input-placeholder));\n font-weight: 400;\n}\n\n/* ===== RESIZE CONTROL OPTIONS ===== */\n\n/* Allow manual resizing */\ntextarea.resize-both {\n resize: both;\n}\n\ntextarea.resize-horizontal {\n resize: horizontal;\n}\n\ntextarea.resize-vertical {\n resize: vertical;\n}\n\ntextarea.resize-none {\n resize: none;\n}\n\n/* Auto-resize mode (default) disables manual resize */\ntextarea:not(.resize-both):not(.resize-horizontal):not(.resize-vertical) {\n resize: none;\n}\n\n/* ===== DUMMY ELEMENT FOR AUTO-RESIZE ===== */\n\n.textarea-dummy {\n /* Hidden element that measures text height */\n position: absolute !important;\n top: 0 !important;\n left: 0 !important;\n visibility: hidden !important;\n white-space: pre-wrap !important;\n word-break: break-word !important;\n box-sizing: border-box !important;\n overflow: hidden !important;\n pointer-events: none !important;\n z-index: -1 !important;\n\n /* Ensure it has the same text behavior as textarea */\n word-wrap: break-word !important;\n overflow-wrap: break-word !important;\n}\n\n/* ===== SIZE MODIFIERS ===== */\n\n/* Extra Small */\ntextarea.xs {\n min-height: 64px;\n padding: 8px 10px;\n font-size: var(--ty-font-xs);\n line-height: var(--ty-leading-xs);\n letter-spacing: var(--ty-tracking-xs);\n}\n\n/* Small */\ntextarea.sm {\n min-height: 72px;\n padding: 10px 10px;\n font-size: var(--ty-font-sm);\n line-height: var(--ty-leading-sm);\n letter-spacing: var(--ty-tracking-sm);\n}\n\n/* Medium (default) */\ntextarea.md {\n min-height: 80px;\n padding: 12px 12px;\n font-size: var(--ty-font-sm);\n line-height: var(--ty-leading-sm);\n letter-spacing: var(--ty-tracking-sm);\n}\n\n/* Large */\ntextarea.lg {\n min-height: 96px;\n padding: 14px 14px;\n font-size: var(--ty-font-base);\n line-height: var(--ty-leading-base);\n letter-spacing: var(--ty-tracking-base);\n}\n\n/* Extra Large */\ntextarea.xl {\n min-height: 112px;\n padding: 16px 16px;\n font-size: var(--ty-font-lg);\n line-height: var(--ty-leading-lg);\n letter-spacing: var(--ty-tracking-lg);\n}\n\n/* ===== ACCESSIBILITY ENHANCEMENTS ===== */\n\ntextarea:focus-visible {\n outline: none;\n /* We use box-shadow instead */\n}\n\n/* High contrast mode support */\n@media (prefers-contrast: high) {\n textarea {\n border-width: 2px;\n }\n}\n\n/* Reduced motion support */\n@media (prefers-reduced-motion: reduce) {\n textarea {\n transition: none;\n }\n\n .textarea-dummy {\n transition: none;\n }\n}\n\n/* ===== CONTAINER-AWARE RESPONSIVE BEHAVIOR ===== */\n\n/* Scale down on smaller containers using container queries */\n@container (max-width: 480px) {\n textarea.lg {\n font-size: var(--ty-font-sm);\n line-height: var(--ty-leading-sm);\n letter-spacing: var(--ty-tracking-sm);\n padding: 12px 12px;\n min-height: 80px;\n }\n\n textarea.xl {\n font-size: var(--ty-font-base);\n line-height: var(--ty-leading-base);\n letter-spacing: var(--ty-tracking-base);\n padding: 14px 14px;\n min-height: 96px;\n }\n}\n\n@container (max-width: 320px) {\n textarea.xl {\n font-size: var(--ty-font-sm);\n line-height: var(--ty-leading-sm);\n letter-spacing: var(--ty-tracking-sm);\n padding: 12px 12px;\n min-height: 80px;\n }\n}\n\n/* Fallback for browsers without container query support */\n@media (max-width: 640px) {\n textarea.lg {\n font-size: var(--ty-font-sm);\n line-height: var(--ty-leading-sm);\n letter-spacing: var(--ty-tracking-sm);\n padding: 12px 12px;\n min-height: 80px;\n }\n\n textarea.xl {\n font-size: var(--ty-font-base);\n line-height: var(--ty-leading-base);\n letter-spacing: var(--ty-tracking-base);\n padding: 14px 14px;\n min-height: 96px;\n }\n}\n\n@media (max-width: 480px) {\n textarea.xl {\n font-size: var(--ty-font-sm);\n line-height: var(--ty-leading-sm);\n letter-spacing: var(--ty-tracking-sm);\n padding: 12px 12px;\n min-height: 80px;\n }\n}\n\n/* ===== ANIMATION AND TRANSITIONS ===== */\n\n/* Smooth height transitions for auto-resize */\ntextarea {\n transition:\n border-color 0.15s ease-in-out,\n box-shadow 0.15s ease-in-out,\n background-color 0.15s ease-in-out,\n height 0.1s ease-out;\n /* Smooth height changes */\n}\n\n/* Disable height transition on focus to avoid jarring effect */\ntextarea:focus {\n transition:\n border-color 0.15s ease-in-out,\n box-shadow 0.15s ease-in-out,\n background-color 0.15s ease-in-out;\n}\n\n/* For users who prefer reduced motion, disable height transitions */\n@media (prefers-reduced-motion: reduce) {\n textarea {\n transition: none;\n }\n}\n";
6
6
  //# sourceMappingURL=textarea.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"textarea.d.ts","sourceRoot":"","sources":["../../src/styles/textarea.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,cAAc,muQAwV1B,CAAA"}
1
+ {"version":3,"file":"textarea.d.ts","sourceRoot":"","sources":["../../src/styles/textarea.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,cAAc,ipTA0X1B,CAAA"}
@@ -18,19 +18,78 @@ export const textareaStyles = `
18
18
  /* For absolute positioned dummy element */
19
19
  }
20
20
 
21
+ /* Bordered container — owns the border + active state (composer layout):
22
+ header (top slot) · textarea (borderless) · footer (bottom slot). */
21
23
  .textarea-wrapper {
22
24
  position: relative;
23
25
  width: 100%;
26
+ display: flex;
27
+ flex-direction: column;
28
+ box-sizing: border-box;
29
+ border: 1px solid var(--input-border, var(--ty-input-border));
30
+ border-radius: 6px;
31
+ background: var(--input-bg, var(--ty-input-bg));
32
+ transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
33
+ }
34
+
35
+ /* Active ring tied to the TEXTAREA specifically (not :focus-within) so tabbing
36
+ to a footer button doesn't make the whole field look focused. */
37
+ .textarea-wrapper:has(textarea:focus) {
38
+ border-color: var(--input-border-focus, var(--ty-input-border-focus));
39
+ box-shadow: 0 0 0 3px var(--input-shadow-focus, var(--ty-input-shadow-focus));
40
+ }
41
+
42
+ /* Error + disabled reflected from the inner textarea (both in shadow DOM, so
43
+ :has is reliable here — unlike slotted content). */
44
+ .textarea-wrapper:has(textarea.error) {
45
+ border-color: var(--ty-color-danger);
46
+ background: var(--ty-bg-danger-soft);
47
+ }
48
+ .textarea-wrapper:has(textarea.error):has(textarea:focus) {
49
+ border-color: var(--ty-color-danger-bold);
50
+ }
51
+ .textarea-wrapper:has(textarea:disabled) {
52
+ opacity: 0.5;
53
+ background: var(--input-disabled-bg, var(--ty-input-disabled-bg));
54
+ border-color: var(--input-disabled-border, var(--ty-input-disabled-border));
24
55
  }
25
56
 
26
- /* Custom scrollbar track positioning within textarea border */
27
- .textarea-wrapper .ty-scrollbar-track-y {
57
+ /* Scroll region wraps just the textarea so the custom scrollbar never overlaps
58
+ the header/footer. */
59
+ .textarea-scroll {
60
+ position: relative;
61
+ flex: 1 1 auto;
62
+ min-height: 0;
63
+ display: flex;
64
+ }
65
+
66
+ /* Custom scrollbar track positioned to the scroll region (textarea edges) */
67
+ .textarea-scroll .ty-scrollbar-track-y {
28
68
  top: 2px;
29
69
  right: 2px;
30
70
  bottom: 2px;
31
71
  border-radius: 0 4px 4px 0;
32
72
  }
33
73
 
74
+ /* Header / footer slot regions — zero footprint until they have content
75
+ (the component toggles .has-content via slotchange). footer defaults to
76
+ space-between so "tools … submit" works; a single wide button fills it. */
77
+ .textarea-header,
78
+ .textarea-footer {
79
+ display: flex;
80
+ align-items: center;
81
+ gap: 0.5rem;
82
+ }
83
+ .textarea-footer { justify-content: space-between; }
84
+ .textarea-header.has-content {
85
+ padding: 6px 10px;
86
+ border-bottom: 1px solid var(--ty-textarea-divider, var(--input-border, var(--ty-input-border)));
87
+ }
88
+ .textarea-footer.has-content {
89
+ padding: 6px 10px;
90
+ border-top: 1px solid var(--ty-textarea-divider, var(--input-border, var(--ty-input-border)));
91
+ }
92
+
34
93
  /* ===== LABEL STYLING ===== */
35
94
 
36
95
  .ty-field-label {
@@ -64,26 +123,17 @@ export const textareaStyles = `
64
123
  padding-left: 12px;
65
124
  }
66
125
 
67
- /* Error state for textareas */
68
- textarea.error {
69
- border-color: var(--ty-color-danger);
70
- background: var(--ty-bg-danger-soft);
71
- }
72
-
73
- textarea.error:focus {
74
- border-color: var(--ty-color-danger-bold);
75
- box-shadow: 0 0 0 3px var(--input-shadow-focus, var(--ty-input-shadow-focus));
76
- }
126
+ /* Error state is reflected on .textarea-wrapper (see above). */
77
127
 
78
128
  /* ===== TEXTAREA BASE STYLING ===== */
79
129
 
80
130
  textarea {
81
- /* Base appearance elegant and minimal like input */
131
+ /* Borderlessthe .textarea-wrapper owns the border/background now. */
82
132
  box-sizing: border-box;
83
133
  width: 100%;
84
- border: 1px solid var(--input-border, var(--ty-input-border));
85
- border-radius: 6px;
86
- background: var(--input-bg, var(--ty-input-bg));
134
+ flex: 1 1 auto;
135
+ border: none;
136
+ background: transparent;
87
137
  color: var(--input-color, var(--ty-input-color));
88
138
  font-family: inherit;
89
139
  /* Linear-paired typography */
@@ -91,7 +141,6 @@ textarea {
91
141
  line-height: var(--ty-leading-sm);
92
142
  letter-spacing: var(--ty-tracking-sm);
93
143
  font-weight: var(--ty-font-normal);
94
- transition: all 0.15s ease-in-out;
95
144
  outline: none;
96
145
 
97
146
  /* Default size (md) - refined spacing */
@@ -117,24 +166,9 @@ textarea {
117
166
  display: none;
118
167
  }
119
168
 
120
- /* Focus state - elegant blue glow like input */
121
- textarea:focus {
122
- border-color: var(--input-border-focus, var(--ty-input-border-focus));
123
- box-shadow: 0 0 0 3px var(--input-shadow-focus, var(--ty-input-shadow-focus));
124
- background: var(--input-bg, var(--ty-input-bg));
125
- }
126
-
127
- /* Hover state - subtle feedback */
128
- textarea:hover:not(:disabled) {
129
- border-color: var(--input-border-hover, var(--ty-input-border-hover));
130
- }
131
-
132
- /* Disabled state - refined opacity */
169
+ /* Disabled — visual state lives on the wrapper; just the cursor/text here. */
133
170
  textarea:disabled {
134
171
  cursor: not-allowed;
135
- opacity: 0.5;
136
- background: var(--input-disabled-bg, var(--ty-input-disabled-bg));
137
- border-color: var(--input-disabled-border, var(--ty-input-disabled-border));
138
172
  color: var(--input-disabled-color, var(--ty-input-disabled-color));
139
173
  }
140
174
 
@@ -1 +1 @@
1
- {"version":3,"file":"textarea.js","sourceRoot":"","sources":["../../src/styles/textarea.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwV7B,CAAA"}
1
+ {"version":3,"file":"textarea.js","sourceRoot":"","sources":["../../src/styles/textarea.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0X7B,CAAA"}
package/lib/version.d.ts CHANGED
@@ -4,5 +4,5 @@
4
4
  * This is automatically synced with package.json during build.
5
5
  * Use `npm version` to bump versions.
6
6
  */
7
- export declare const VERSION = "1.0.0-TC23";
7
+ export declare const VERSION = "1.0.0-TC25";
8
8
  //# sourceMappingURL=version.d.ts.map
package/lib/version.js CHANGED
@@ -7,5 +7,5 @@
7
7
  * This is automatically synced with package.json during build.
8
8
  * Use `npm version` to bump versions.
9
9
  */
10
- export const VERSION = '1.0.0-TC23';
10
+ export const VERSION = '1.0.0-TC25';
11
11
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tyrell-components",
3
- "version": "1.0.0-TC23",
3
+ "version": "1.0.0-TC25",
4
4
  "description": "Tyrell Components - Framework-agnostic web components with semantic design system",
5
5
  "type": "module",
6
6
  "sideEffects": [
@@ -140,11 +140,19 @@
140
140
  "build:dev:watch": "vite build --config vite.config.dev.ts --watch",
141
141
  "build": "npm run build:lib && npm run build:cdn",
142
142
  "prepublishOnly": "npm run build",
143
- "preview": "vite preview"
143
+ "preview": "vite preview",
144
+ "test": "npm run build:lib && wtr",
145
+ "test:watch": "wtr --watch"
144
146
  },
145
147
  "devDependencies": {
148
+ "@open-wc/testing": "^4.0.0",
146
149
  "@rollup/plugin-terser": "^0.4.4",
150
+ "@types/mocha": "^10.0.10",
151
+ "@web/dev-server-esbuild": "^1.0.5",
152
+ "@web/test-runner": "^0.20.2",
153
+ "@web/test-runner-chrome": "^0.18.1",
147
154
  "autoprefixer": "^10.4.27",
155
+ "axe-core": "^4.12.1",
148
156
  "typescript": "^5.7.0",
149
157
  "vite": "^5.4.11",
150
158
  "vite-plugin-dts": "^4.5.4"