diff --git a/src/components/Root.tsx b/src/components/Root.tsx index df63f17cb..d91e8e490 100644 --- a/src/components/Root.tsx +++ b/src/components/Root.tsx @@ -62,7 +62,6 @@ export function Root(allProps: CubeRootProps) { children, /** Raw css styles for body element */ bodyStyles, - breakpoints = [980], fontDisplay = 'swap', fonts, publicUrl, @@ -128,7 +127,7 @@ export function Root(allProps: CubeRootProps) { const styles = extractStyles(props, STYLES, DEFAULT_STYLES); return ( - + /** * Whether the text has italic style */ - italic?: ResponsiveStyleValue; + italic?: StylePropValue; weight?: string | number; - transform?: ResponsiveStyleValue; + transform?: StylePropValue; } const TextElement = tasty({ diff --git a/src/provider.tsx b/src/provider.tsx index aaebc7363..c65776aad 100644 --- a/src/provider.tsx +++ b/src/provider.tsx @@ -9,11 +9,10 @@ import { import { NavigationAdapter } from './providers/navigation.types'; import { defaultNavigationAdapter } from './providers/navigationAdapter.default'; -import { BreakpointsProvider, Props } from './tasty'; +import { Props } from './tasty'; import { EventBusProvider } from './utils/react/useEventBus'; export interface ProviderProps extends Props { - breakpoints?: number[]; insideForm?: boolean; isDisabled?: boolean; isReadOnly?: boolean; @@ -24,7 +23,7 @@ export interface ProviderProps extends Props { root?: ForwardedRef; } -export type ProviderInsideProps = Omit; +export type ProviderInsideProps = Omit; export const UIKitContext = createContext({ navigation: defaultNavigationAdapter, @@ -32,7 +31,6 @@ export const UIKitContext = createContext({ export function Provider(allProps: PropsWithChildren) { let { - breakpoints, children, insideForm, isDisabled, @@ -46,19 +44,12 @@ export function Provider(allProps: PropsWithChildren) { const parentContext = useContext(UIKitContext); - if (breakpoints) { - children = ( - {children} - ); - } - // Wrap with EventBusProvider for menu synchronization children = {children}; const props = useMemo( () => ({ ref, - breakpoints, insideForm, isDisabled, isReadOnly, @@ -69,7 +60,6 @@ export function Provider(allProps: PropsWithChildren) { }), [ ref, - breakpoints, insideForm, isDisabled, isReadOnly, diff --git a/src/stories/Tasty.docs.mdx b/src/stories/Tasty.docs.mdx index b26dcf19d..0b6bfe0d9 100644 --- a/src/stories/Tasty.docs.mdx +++ b/src/stories/Tasty.docs.mdx @@ -53,13 +53,6 @@ const PrimaryButton = tasty(Button, { ### Essential Patterns ```jsx -// Responsive styling -const ResponsiveBox = tasty({ - styles: { - padding: ['4x', '2x', '1x'], // Large → Medium → Small screens - }, -}); - // State-based styling const InteractiveCard = tasty({ styles: { @@ -133,14 +126,6 @@ fill: '#purple.5' // → var(--purple-color) with 50% opacity Shorthand units referencing design system values: `x` (gap), `r` (radius), `bw` (border-width), `fs` (font-size), `sf` (stable grid fractions). -### Responsive Array - -Array of values mapping to breakpoints (large to small). Configure with ``. - -```jsx -padding: ['4x', '2x', '1x'] // Large → Medium → Small -``` - ### Style Props Style properties exposed as direct props via `styleProps` config. Provides cleaner API than using `styles` prop. @@ -219,7 +204,6 @@ const FlexibleBox = tasty({ - **Cleaner API** - No need for `styles` prop wrapper - **Better TypeScript support** - Props are properly typed - **Component-specific styling** - Expose only relevant properties -- **Responsive support** - Works with arrays: `gap={['2x', '1x']}` - **State-based styling** - Works with objects: `fill={{ '': '#white', hovered: '#gray' }}` **Style Prop Priority:** @@ -243,7 +227,6 @@ const FlexibleBox = tasty({ Tasty enhances CSS with: - **Design tokens** - `#purple`, `#text`, `#border` - **Custom units** - `2x` (gap), `1r` (radius), `1bw` (border-width) -- **Responsive arrays** - `['4x', '2x', '1x']` - **State objects** - `{ '': 'default', hovered: 'hover-state' }` - **Smart defaults** - `border: true` uses design system values @@ -284,23 +267,6 @@ color: '#purple.05', // 5% opacity > gridColumns="1sf 2sf 1sf" // equivalent to "minmax(0, 1fr) minmax(0, 2fr) minmax(0, 1fr)" > ``` -### Responsive Styling - -Configure breakpoints and use responsive arrays: - -```jsx -// Configure breakpoints (optional) - - - - -// Use responsive arrays - -// Large screens (≥1200px): 4x -// Medium screens (640px-1199px): 2x -// Small screens (<640px): 1x -``` - --- ## 📖 Style Properties Reference @@ -353,7 +319,6 @@ padding: '2x 1x', // Vertical, horizontal padding: '2x top', // Top only padding: '1x left right', // Left and right padding: true, // Default: '1x' -padding: ['2x', '1x', '0.5x'], // Responsive array (padding only) // Available modifiers: top, right, bottom, left // Default value (true): '1x' → 'var(--gap)' @@ -878,10 +843,6 @@ styles: { Content: { color: '#text' }, } -// ✅ Use responsive arrays for breakpoints -padding: ['4x', '2x', '1x'] -width: ['max 1200px', 'max 800px', 'max 100%'] - // ✅ Use modifiers for state-based styling styles: { fill: { @@ -1005,15 +966,6 @@ const InteractiveCard = tasty({ }, }); -// Responsive container -const Container = tasty({ - styles: { - padding: ['6x', '4x', '2x'], - width: ['max 1200px', 'max 800px', 'max 100%'], - margin: '0 auto', - }, -}); - // Button with variants const Button = tasty({ styles: { diff --git a/src/tasty/__snapshots__/tasty.test.tsx.snap b/src/tasty/__snapshots__/tasty.test.tsx.snap index 43b1390b5..dd977d447 100644 --- a/src/tasty/__snapshots__/tasty.test.tsx.snap +++ b/src/tasty/__snapshots__/tasty.test.tsx.snap @@ -1,375 +1,29 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`tasty() API should allow multiple wrapping 1`] = `".t14.t14 {position: static; padding-top: calc(2 * var(--gap)); border: var(--border-width) solid var(--black-color); color: var(--white-color); --current-color: var(--white-color, white); --current-color-rgb: var(--white-color-rgb); display: flex;}"`; +exports[`tasty() API should allow multiple wrapping 1`] = `".t13.t13 {position: static; padding-top: calc(2 * var(--gap)); border: var(--border-width) solid var(--black-color); color: var(--white-color); --current-color: var(--white-color, white); --current-color-rgb: var(--white-color-rgb); display: flex;}"`; exports[`tasty() API should allow nested modifiers 1`] = ` -".t15.t15 {display: block;} -.t15.t15:first-child {color: var(--clear-color); --current-color: var(--clear-color, clear); --current-color-rgb: var(--clear-color-rgb);} -.t15.t15:not(:first-child) {color: var(--black-color); --current-color: var(--black-color, black); --current-color-rgb: var(--black-color-rgb);}" +".t14.t14 {display: block;} +.t14.t14:first-child {color: var(--clear-color); --current-color: var(--clear-color, clear); --current-color-rgb: var(--clear-color-rgb);} +.t14.t14:not(:first-child) {color: var(--black-color); --current-color: var(--black-color, black); --current-color-rgb: var(--black-color-rgb);}" `; exports[`tasty() API should be able to override styles 1`] = `".t7.t7 {display: block; color: rgb(var(--black-color-rgb) / .1); --current-color: var(--black-color, black); --current-color-rgb: var(--black-color-rgb);}"`; exports[`tasty() API should create element styles 1`] = ` -".t11.t11:not([data-modified]) [data-element="Element"] {color: var(--dark-color); --current-color: var(--dark-color, dark); --current-color-rgb: var(--dark-color-rgb);} -.t11.t11[data-modified] [data-element="Element"] {color: var(--purple-color); --current-color: var(--purple-color, purple); --current-color-rgb: var(--purple-color-rgb);}" -`; - -exports[`tasty() API should create responsive styles 1`] = ` -"@media (min-width: 980px) {.t10.t10 {display: grid;}} -@media (max-width: 979px) {.t10.t10 {display: flex;}}" +".t10.t10:not([data-modified]) [data-element="Element"] {color: var(--dark-color); --current-color: var(--dark-color, dark); --current-color-rgb: var(--dark-color-rgb);} +.t10.t10[data-modified] [data-element="Element"] {color: var(--purple-color); --current-color: var(--purple-color, purple); --current-color-rgb: var(--purple-color-rgb);}" `; -exports[`tasty() API should define style props 1`] = `".t13.t13 {border: var(--border-width) solid var(--border-color);}"`; +exports[`tasty() API should define style props 1`] = `".t12.t12 {border: var(--border-width) solid var(--border-color);}"`; exports[`tasty() API should fallback to default variant 1`] = `".t9.t9 {color: var(--white-color); --current-color: var(--white-color, white); --current-color-rgb: var(--white-color-rgb);}"`; -exports[`tasty() API should handle arrays containing state maps 1`] = ` -".t19.t19 {display: block;} -@media (min-width: 1200px) {.t19.t19 {padding-top: calc(2 * var(--gap)); padding-right: calc(2 * var(--gap)); padding-bottom: calc(2 * var(--gap)); padding-left: calc(2 * var(--gap)); margin-top: var(--gap); margin-right: var(--gap); margin-bottom: var(--gap); margin-left: var(--gap);}} -@media (min-width: 768px) and (max-width: 1199px) {.t19.t19:not([data-hovered]) {padding-top: var(--gap); padding-right: var(--gap); padding-bottom: var(--gap); padding-left: var(--gap); background-color: rgb(var(--gray-color-rgb) / .05);}} -@media (min-width: 768px) and (max-width: 1199px) {.t19.t19[data-hovered] {padding-top: calc(3 * var(--gap)); padding-right: calc(3 * var(--gap)); padding-bottom: calc(3 * var(--gap)); padding-left: calc(3 * var(--gap)); background-color: rgb(var(--blue-color-rgb) / .10);}} -@media (max-width: 767px) {.t19.t19:not([data-hovered]) {padding-top: var(--gap); padding-right: var(--gap); padding-bottom: var(--gap); padding-left: var(--gap); background-color: rgb(var(--gray-color-rgb) / .05);}} -@media (max-width: 767px) {.t19.t19[data-hovered] {padding-top: calc(3 * var(--gap)); padding-right: calc(3 * var(--gap)); padding-bottom: calc(3 * var(--gap)); padding-left: calc(3 * var(--gap)); background-color: rgb(var(--blue-color-rgb) / .10);}} -@media (min-width: 768px) and (max-width: 1199px) {.t19.t19:not([data-disabled]):not([data-pressed]) {margin-top: calc(2 * var(--gap)); margin-right: calc(2 * var(--gap)); margin-bottom: calc(2 * var(--gap)); margin-left: calc(2 * var(--gap));}} -@media (min-width: 768px) and (max-width: 1199px) {.t19.t19[data-disabled]:not([data-pressed]) {margin-top: 0; margin-right: 0; margin-bottom: 0; margin-left: 0;}} -@media (min-width: 768px) and (max-width: 1199px) {.t19.t19[data-pressed]:not([data-disabled]) {margin-top: var(--gap); margin-right: var(--gap); margin-bottom: var(--gap); margin-left: var(--gap);}} -@media (min-width: 768px) and (max-width: 1199px) {.t19.t19[data-disabled][data-pressed] {margin-top: 0; margin-right: 0; margin-bottom: 0; margin-left: 0;}} -@media (max-width: 767px) {.t19.t19:not([data-focused]) {margin-top: calc(0.5 * var(--gap)); margin-right: calc(0.5 * var(--gap)); margin-bottom: calc(0.5 * var(--gap)); margin-left: calc(0.5 * var(--gap));}} -@media (max-width: 767px) {.t19.t19[data-focused] {margin-top: var(--gap); margin-right: var(--gap); margin-bottom: var(--gap); margin-left: var(--gap);}} -@media (min-width: 1200px) {.t19.t19:not([data-hovered]) {background-color: var(--white-color);}} -@media (min-width: 1200px) {.t19.t19:not([data-hovered])>* {--context-fill-color: var(--white-color); --context-fill-color-rgb: var(--white-color-rgb);}} -@media (min-width: 1200px) {.t19.t19[data-hovered] {background-color: rgb(var(--blue-color-rgb) / .05);}} -@media (min-width: 1200px) {.t19.t19[data-hovered]>* {--context-fill-color: rgb(var(--blue-color-rgb) / .05); --context-fill-color-rgb: var(--blue-color-rgb);}} -@media (min-width: 768px) and (max-width: 1199px) {.t19.t19:not([data-hovered])>* {--context-fill-color: rgb(var(--gray-color-rgb) / .05); --context-fill-color-rgb: var(--gray-color-rgb);}} -@media (min-width: 768px) and (max-width: 1199px) {.t19.t19[data-hovered]>* {--context-fill-color: rgb(var(--blue-color-rgb) / .10); --context-fill-color-rgb: var(--blue-color-rgb);}} -@media (max-width: 767px) {.t19.t19:not([data-hovered])>* {--context-fill-color: rgb(var(--gray-color-rgb) / .05); --context-fill-color-rgb: var(--gray-color-rgb);}} -@media (max-width: 767px) {.t19.t19[data-hovered]>* {--context-fill-color: rgb(var(--blue-color-rgb) / .10); --context-fill-color-rgb: var(--blue-color-rgb);}}" -`; - -exports[`tasty() API should handle complex gridAreas with responsive arrays and state modifiers 1`] = ` -".t23.t23:not([data-sticky]) {position: static; background-color: transparent; z-index: auto; box-shadow: none;} -.t23.t23[data-sticky] {position: sticky; top: 0; background-color: var(--white-color); z-index: 10; box-shadow: 0 calc(0.5 * var(--gap)) calc(0.5 * var(--gap)) var(--white-color);} -.t23.t23[data-sticky]>* {--context-fill-color: var(--white-color); --context-fill-color-rgb: var(--white-color-rgb);} -.t23.t23 {display: grid; padding-top: var(--gap); padding-right: calc(2 * var(--gap)); padding-bottom: var(--gap); padding-left: calc(2 * var(--gap)); height: auto; min-height: calc(6 * var(--gap)); max-height: initial; place-items: center stretch; place-content: stretch;} -@media (min-width: 1200px) {.t23.t23:not([data-back-button-top]) {grid-template-areas: "breadcrumbs breadcrumbs breadcrumbs breadcrumbs breadcrumbs breadcrumbs" "back title . subtitle spacer extra" "back title . subtitle spacer extra" "content content content content content content" "footer footer footer footer footer footer";}} -@media (min-width: 1200px) {.t23.t23[data-back-button-top] {grid-template-areas: "back back back back back back" "breadcrumbs breadcrumbs breadcrumbs breadcrumbs breadcrumbs breadcrumbs" ". title . subtitle spacer extra" ". title . subtitle spacer extra" "content content content content content content" "footer footer footer footer footer footer";}} -@media (max-width: 1199px) {.t23.t23:not([data-back-button-top]) {grid-template-areas: "breadcrumbs breadcrumbs breadcrumbs breadcrumbs" "back title spacer extra" "back subtitle subtitle extra" "back . . extra" "content content content content" "footer footer footer footer";}} -@media (max-width: 1199px) {.t23.t23[data-back-button-top] {grid-template-areas: "back back back back" "breadcrumbs breadcrumbs breadcrumbs breadcrumbs" ". title spacer extra" ". subtitle subtitle extra" ". . . extra" "content content content content" "footer footer footer footer";}} -@media (min-width: 1200px) {.t23.t23 {grid-template-columns: max-content minmax(calc(2 * var(--gap)), auto) calc(2 * var(--gap)) minmax(0, auto) minmax(calc(2 * var(--gap)), 1fr) minmax(min-content, max-content);}} -@media (max-width: 1199px) {.t23.t23 {grid-template-columns: max-content minmax(calc(2 * var(--gap)), auto) minmax(calc(2 * var(--gap)), 1fr) minmax(min-content, max-content);}}" -`; - -exports[`tasty() API should handle complex responsive styles with state binding 1`] = ` -"@media (min-width: 1200px) {.t22.t22 [data-element="Header"] {--font-size: var(--h2-font-size, var(--default-font-size, inherit)); font-size: var(--h2-font-size, var(--default-font-size, inherit)); --line-height: var(--h2-line-height, var(--default-line-height, inherit)); line-height: var(--h2-line-height, var(--default-line-height, inherit)); --letter-spacing: var(--h2-letter-spacing, var(--default-letter-spacing, inherit)); letter-spacing: var(--h2-letter-spacing, var(--default-letter-spacing, inherit)); --font-weight: var(--h2-font-weight, var(--default-font-weight, inherit)); font-weight: var(--h2-font-weight, var(--default-font-weight, inherit)); --font-style: var(--h2-font-style, var(--default-font-style, inherit)); font-style: var(--h2-font-style, var(--default-font-style, inherit)); --text-transform: var(--h2-text-transform, var(--default-text-transform, inherit)); text-transform: var(--h2-text-transform, var(--default-text-transform, inherit)); --font-family: var(--h2-font-family, var(--default-font-family, var(--font, NonexistentFontName))), var(--font, sans-serif); font-family: var(--h2-font-family, var(--default-font-family, var(--font, NonexistentFontName))), var(--font, sans-serif); --bold-font-weight: var(--h2-bold-font-weight, var(--default-bold-font-weight, inherit)); --icon-size: var(--h2-icon-size, var(--default-icon-size, inherit)); margin-top: 0; margin-right: 0; margin-bottom: calc(2 * var(--gap)); margin-left: 0;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22 [data-element="Header"] {--font-size: var(--h3-font-size, var(--default-font-size, inherit)); font-size: var(--h3-font-size, var(--default-font-size, inherit)); --line-height: var(--h3-line-height, var(--default-line-height, inherit)); line-height: var(--h3-line-height, var(--default-line-height, inherit)); --letter-spacing: var(--h3-letter-spacing, var(--default-letter-spacing, inherit)); letter-spacing: var(--h3-letter-spacing, var(--default-letter-spacing, inherit)); --font-weight: var(--h3-font-weight, var(--default-font-weight, inherit)); font-weight: var(--h3-font-weight, var(--default-font-weight, inherit)); --font-style: var(--h3-font-style, var(--default-font-style, inherit)); font-style: var(--h3-font-style, var(--default-font-style, inherit)); --text-transform: var(--h3-text-transform, var(--default-text-transform, inherit)); text-transform: var(--h3-text-transform, var(--default-text-transform, inherit)); --font-family: var(--h3-font-family, var(--default-font-family, var(--font, NonexistentFontName))), var(--font, sans-serif); font-family: var(--h3-font-family, var(--default-font-family, var(--font, NonexistentFontName))), var(--font, sans-serif); --bold-font-weight: var(--h3-bold-font-weight, var(--default-bold-font-weight, inherit)); --icon-size: var(--h3-icon-size, var(--default-icon-size, inherit)); margin-top: 0; margin-right: 0; margin-bottom: var(--gap); margin-left: 0;}} -@media (max-width: 767px) {.t22.t22 [data-element="Header"] {--font-size: var(--h4-font-size, var(--default-font-size, inherit)); font-size: var(--h4-font-size, var(--default-font-size, inherit)); --line-height: var(--h4-line-height, var(--default-line-height, inherit)); line-height: var(--h4-line-height, var(--default-line-height, inherit)); --letter-spacing: var(--h4-letter-spacing, var(--default-letter-spacing, inherit)); letter-spacing: var(--h4-letter-spacing, var(--default-letter-spacing, inherit)); --font-weight: var(--h4-font-weight, var(--default-font-weight, inherit)); font-weight: var(--h4-font-weight, var(--default-font-weight, inherit)); --font-style: var(--h4-font-style, var(--default-font-style, inherit)); font-style: var(--h4-font-style, var(--default-font-style, inherit)); --text-transform: var(--h4-text-transform, var(--default-text-transform, inherit)); text-transform: var(--h4-text-transform, var(--default-text-transform, inherit)); --font-family: var(--h4-font-family, var(--default-font-family, var(--font, NonexistentFontName))), var(--font, sans-serif); font-family: var(--h4-font-family, var(--default-font-family, var(--font, NonexistentFontName))), var(--font, sans-serif); --bold-font-weight: var(--h4-bold-font-weight, var(--default-bold-font-weight, inherit)); --icon-size: var(--h4-icon-size, var(--default-icon-size, inherit)); margin-top: 0; margin-right: 0; margin-bottom: calc(0.5 * var(--gap)); margin-left: 0;}} -.t22.t22:not([data-hovered]):not([data-variant="danger"]) [data-element="Header"] {color: var(--text-primary-color); --current-color: var(--text-primary-color, text-primary); --current-color-rgb: var(--text-primary-color-rgb);} -.t22.t22[data-hovered]:not([data-variant="danger"]) [data-element="Header"] {color: var(--text-primary-hover-color); --current-color: var(--text-primary-hover-color, text-primary-hover); --current-color-rgb: var(--text-primary-hover-color-rgb);} -.t22.t22[data-variant="danger"]:not([data-hovered]) [data-element="Header"] {color: var(--danger-color); --current-color: var(--danger-color, danger); --current-color-rgb: var(--danger-color-rgb);} -.t22.t22[data-hovered][data-variant="danger"] [data-element="Header"] {color: var(--text-primary-hover-color); --current-color: var(--text-primary-hover-color, text-primary-hover); --current-color-rgb: var(--text-primary-hover-color-rgb);} -@media (min-width: 1200px) {.t22.t22 [data-element="Content"] {padding-top: calc(2 * var(--gap)); padding-right: calc(2 * var(--gap)); padding-bottom: calc(2 * var(--gap)); padding-left: calc(2 * var(--gap));}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22 [data-element="Content"] {padding-top: var(--gap); padding-right: var(--gap); padding-bottom: var(--gap); padding-left: var(--gap);}} -@media (max-width: 767px) {.t22.t22 [data-element="Content"] {padding-top: calc(0.5 * var(--gap)); padding-right: calc(0.5 * var(--gap)); padding-bottom: calc(0.5 * var(--gap)); padding-left: calc(0.5 * var(--gap));}} -.t22.t22:not([data-highlighted]):not([data-disabled]) [data-element="Content"] {color: var(--text-color); --current-color: var(--text-color, text); --current-color-rgb: var(--text-color-rgb);} -.t22.t22[data-highlighted]:not([data-disabled]) [data-element="Content"] {color: var(--text-highlighted-color); --current-color: var(--text-highlighted-color, text-highlighted); --current-color-rgb: var(--text-highlighted-color-rgb);} -.t22.t22[data-disabled]:not([data-highlighted]) [data-element="Content"] {color: var(--text-disabled-color); --current-color: var(--text-disabled-color, text-disabled); --current-color-rgb: var(--text-disabled-color-rgb);} -.t22.t22[data-highlighted][data-disabled] [data-element="Content"] {color: var(--text-disabled-color); --current-color: var(--text-disabled-color, text-disabled); --current-color-rgb: var(--text-disabled-color-rgb);} -@media (min-width: 1200px) {.t22.t22:not([data-expanded]) [data-element="Footer"] {display: flex; gap: calc(2 * var(--gap));}} -@media (min-width: 1200px) {.t22.t22[data-expanded] [data-element="Footer"] {display: flex; gap: calc(2 * var(--gap));}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22:not([data-expanded]) [data-element="Footer"] {display: flex; gap: var(--gap);}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-expanded] [data-element="Footer"] {display: flex; gap: var(--gap);}} -@media (max-width: 767px) {.t22.t22:not([data-expanded]) [data-element="Footer"] {display: none;}} -@media (max-width: 767px) {.t22.t22[data-expanded] [data-element="Footer"] {display: flex; gap: calc(0.5 * var(--gap));}} -@media (max-width: 767px) {.t22.t22:not([data-expanded]) [data-element="Footer"] > *:not(:last-child) {margin-bottom: calc(0.5 * var(--gap));}} -@media (min-width: 1200px) {.t22.t22:not([data-compact]) [data-element="Footer"] {padding-top: calc(2 * var(--gap));}} -@media (min-width: 1200px) {.t22.t22[data-compact] [data-element="Footer"] {padding-top: var(--gap);}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22:not([data-compact]) [data-element="Footer"] {padding-top: var(--gap);}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-compact] [data-element="Footer"] {padding-top: calc(0.5 * var(--gap));}} -@media (max-width: 767px) {.t22.t22:not([data-compact]) [data-element="Footer"] {padding-top: calc(0.5 * var(--gap));}} -@media (max-width: 767px) {.t22.t22[data-compact] [data-element="Footer"] {padding-top: 0; padding-right: 0; padding-bottom: 0; padding-left: 0;}} -@media (min-width: 1200px) {.t22.t22 {display: grid; gap: calc(3 * var(--gap)); --local-radius: calc(2 * var(--radius)); border-radius: var(--local-radius);}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22 {display: flex; gap: calc(2 * var(--gap)); --local-radius: var(--radius); border-radius: var(--local-radius);}} -@media (max-width: 767px) {.t22.t22 {display: block; --local-radius: calc(0.5 * var(--radius)); border-radius: var(--local-radius);}} -@media (max-width: 767px) {.t22.t22 > *:not(:last-child) {margin-bottom: var(--gap);}} -@media (min-width: 1200px) {.t22.t22:not([data-variant="compact"]):not([data-pressed]):not([data-disabled]):not([data-hovered]) {padding-top: calc(4 * var(--gap)); padding-right: calc(4 * var(--gap)); padding-bottom: calc(4 * var(--gap)); padding-left: calc(4 * var(--gap));}} -@media (min-width: 1200px) {.t22.t22[data-variant="compact"]:not([data-pressed]):not([data-disabled]):not([data-hovered]) {padding-top: calc(2 * var(--gap)); padding-right: calc(2 * var(--gap)); padding-bottom: calc(2 * var(--gap)); padding-left: calc(2 * var(--gap));}} -@media (min-width: 1200px) {.t22.t22[data-pressed]:not([data-variant="compact"]):not([data-disabled]):not([data-hovered]) {padding-top: calc(3 * var(--gap)); padding-right: calc(3 * var(--gap)); padding-bottom: calc(3 * var(--gap)); padding-left: calc(3 * var(--gap));}} -@media (min-width: 1200px) {.t22.t22[data-variant="compact"][data-pressed]:not([data-disabled]):not([data-hovered]) {padding-top: calc(2 * var(--gap)); padding-right: calc(2 * var(--gap)); padding-bottom: calc(2 * var(--gap)); padding-left: calc(2 * var(--gap));}} -@media (min-width: 1200px) {.t22.t22[data-disabled]:not([data-variant="compact"]):not([data-pressed]):not([data-hovered]) {padding-top: calc(4 * var(--gap)); padding-right: calc(4 * var(--gap)); padding-bottom: calc(4 * var(--gap)); padding-left: calc(4 * var(--gap));}} -@media (min-width: 1200px) {.t22.t22[data-variant="compact"][data-disabled]:not([data-pressed]):not([data-hovered]) {padding-top: calc(2 * var(--gap)); padding-right: calc(2 * var(--gap)); padding-bottom: calc(2 * var(--gap)); padding-left: calc(2 * var(--gap));}} -@media (min-width: 1200px) {.t22.t22[data-pressed][data-disabled]:not([data-variant="compact"]):not([data-hovered]) {padding-top: calc(4 * var(--gap)); padding-right: calc(4 * var(--gap)); padding-bottom: calc(4 * var(--gap)); padding-left: calc(4 * var(--gap));}} -@media (min-width: 1200px) {.t22.t22[data-variant="compact"][data-pressed][data-disabled]:not([data-hovered]) {padding-top: calc(2 * var(--gap)); padding-right: calc(2 * var(--gap)); padding-bottom: calc(2 * var(--gap)); padding-left: calc(2 * var(--gap));}} -@media (min-width: 1200px) {.t22.t22[data-hovered]:not([data-variant="compact"]):not([data-pressed]):not([data-disabled]) {padding-top: calc(5 * var(--gap)); padding-right: calc(5 * var(--gap)); padding-bottom: calc(5 * var(--gap)); padding-left: calc(5 * var(--gap));}} -@media (min-width: 1200px) {.t22.t22[data-variant="compact"][data-hovered]:not([data-pressed]):not([data-disabled]) {padding-top: calc(2 * var(--gap)); padding-right: calc(2 * var(--gap)); padding-bottom: calc(2 * var(--gap)); padding-left: calc(2 * var(--gap));}} -@media (min-width: 1200px) {.t22.t22[data-pressed][data-hovered]:not([data-variant="compact"]):not([data-disabled]) {padding-top: calc(3 * var(--gap)); padding-right: calc(3 * var(--gap)); padding-bottom: calc(3 * var(--gap)); padding-left: calc(3 * var(--gap));}} -@media (min-width: 1200px) {.t22.t22[data-variant="compact"][data-pressed][data-hovered]:not([data-disabled]) {padding-top: calc(2 * var(--gap)); padding-right: calc(2 * var(--gap)); padding-bottom: calc(2 * var(--gap)); padding-left: calc(2 * var(--gap));}} -@media (min-width: 1200px) {.t22.t22[data-disabled][data-hovered]:not([data-variant="compact"]):not([data-pressed]) {padding-top: calc(5 * var(--gap)); padding-right: calc(5 * var(--gap)); padding-bottom: calc(5 * var(--gap)); padding-left: calc(5 * var(--gap));}} -@media (min-width: 1200px) {.t22.t22[data-variant="compact"][data-disabled][data-hovered]:not([data-pressed]) {padding-top: calc(2 * var(--gap)); padding-right: calc(2 * var(--gap)); padding-bottom: calc(2 * var(--gap)); padding-left: calc(2 * var(--gap));}} -@media (min-width: 1200px) {.t22.t22[data-pressed][data-disabled][data-hovered]:not([data-variant="compact"]) {padding-top: calc(5 * var(--gap)); padding-right: calc(5 * var(--gap)); padding-bottom: calc(5 * var(--gap)); padding-left: calc(5 * var(--gap));}} -@media (min-width: 1200px) {.t22.t22[data-variant="compact"][data-pressed][data-disabled][data-hovered] {padding-top: calc(2 * var(--gap)); padding-right: calc(2 * var(--gap)); padding-bottom: calc(2 * var(--gap)); padding-left: calc(2 * var(--gap));}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22:not([data-variant="compact"]):not([data-pressed]):not([data-disabled]):not([data-hovered]) {padding-top: calc(3 * var(--gap)); padding-right: calc(3 * var(--gap)); padding-bottom: calc(3 * var(--gap)); padding-left: calc(3 * var(--gap));}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-variant="compact"]:not([data-pressed]):not([data-disabled]):not([data-hovered]) {padding-top: var(--gap); padding-right: var(--gap); padding-bottom: var(--gap); padding-left: var(--gap);}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-pressed]:not([data-variant="compact"]):not([data-disabled]):not([data-hovered]) {padding-top: calc(2 * var(--gap)); padding-right: calc(2 * var(--gap)); padding-bottom: calc(2 * var(--gap)); padding-left: calc(2 * var(--gap));}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-variant="compact"][data-pressed]:not([data-disabled]):not([data-hovered]) {padding-top: var(--gap); padding-right: var(--gap); padding-bottom: var(--gap); padding-left: var(--gap);}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-disabled]:not([data-variant="compact"]):not([data-pressed]):not([data-hovered]) {padding-top: calc(3 * var(--gap)); padding-right: calc(3 * var(--gap)); padding-bottom: calc(3 * var(--gap)); padding-left: calc(3 * var(--gap));}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-variant="compact"][data-disabled]:not([data-pressed]):not([data-hovered]) {padding-top: var(--gap); padding-right: var(--gap); padding-bottom: var(--gap); padding-left: var(--gap);}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-pressed][data-disabled]:not([data-variant="compact"]):not([data-hovered]) {padding-top: calc(3 * var(--gap)); padding-right: calc(3 * var(--gap)); padding-bottom: calc(3 * var(--gap)); padding-left: calc(3 * var(--gap));}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-variant="compact"][data-pressed][data-disabled]:not([data-hovered]) {padding-top: var(--gap); padding-right: var(--gap); padding-bottom: var(--gap); padding-left: var(--gap);}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-hovered]:not([data-variant="compact"]):not([data-pressed]):not([data-disabled]) {padding-top: calc(4 * var(--gap)); padding-right: calc(4 * var(--gap)); padding-bottom: calc(4 * var(--gap)); padding-left: calc(4 * var(--gap));}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-variant="compact"][data-hovered]:not([data-pressed]):not([data-disabled]) {padding-top: var(--gap); padding-right: var(--gap); padding-bottom: var(--gap); padding-left: var(--gap);}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-pressed][data-hovered]:not([data-variant="compact"]):not([data-disabled]) {padding-top: calc(2 * var(--gap)); padding-right: calc(2 * var(--gap)); padding-bottom: calc(2 * var(--gap)); padding-left: calc(2 * var(--gap));}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-variant="compact"][data-pressed][data-hovered]:not([data-disabled]) {padding-top: var(--gap); padding-right: var(--gap); padding-bottom: var(--gap); padding-left: var(--gap);}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-disabled][data-hovered]:not([data-variant="compact"]):not([data-pressed]) {padding-top: calc(4 * var(--gap)); padding-right: calc(4 * var(--gap)); padding-bottom: calc(4 * var(--gap)); padding-left: calc(4 * var(--gap));}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-variant="compact"][data-disabled][data-hovered]:not([data-pressed]) {padding-top: var(--gap); padding-right: var(--gap); padding-bottom: var(--gap); padding-left: var(--gap);}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-pressed][data-disabled][data-hovered]:not([data-variant="compact"]) {padding-top: calc(4 * var(--gap)); padding-right: calc(4 * var(--gap)); padding-bottom: calc(4 * var(--gap)); padding-left: calc(4 * var(--gap));}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-variant="compact"][data-pressed][data-disabled][data-hovered] {padding-top: var(--gap); padding-right: var(--gap); padding-bottom: var(--gap); padding-left: var(--gap);}} -@media (max-width: 767px) {.t22.t22:not([data-variant="compact"]):not([data-pressed]):not([data-disabled]):not([data-hovered]) {padding-top: calc(2 * var(--gap)); padding-right: calc(2 * var(--gap)); padding-bottom: calc(2 * var(--gap)); padding-left: calc(2 * var(--gap));}} -@media (max-width: 767px) {.t22.t22[data-variant="compact"]:not([data-pressed]):not([data-disabled]):not([data-hovered]) {padding-top: calc(0.5 * var(--gap)); padding-right: calc(0.5 * var(--gap)); padding-bottom: calc(0.5 * var(--gap)); padding-left: calc(0.5 * var(--gap));}} -@media (max-width: 767px) {.t22.t22[data-pressed]:not([data-variant="compact"]):not([data-disabled]):not([data-hovered]) {padding-top: var(--gap); padding-right: var(--gap); padding-bottom: var(--gap); padding-left: var(--gap);}} -@media (max-width: 767px) {.t22.t22[data-variant="compact"][data-pressed]:not([data-disabled]):not([data-hovered]) {padding-top: calc(0.5 * var(--gap)); padding-right: calc(0.5 * var(--gap)); padding-bottom: calc(0.5 * var(--gap)); padding-left: calc(0.5 * var(--gap));}} -@media (max-width: 767px) {.t22.t22[data-disabled]:not([data-variant="compact"]):not([data-pressed]):not([data-hovered]) {padding-top: calc(2 * var(--gap)); padding-right: calc(2 * var(--gap)); padding-bottom: calc(2 * var(--gap)); padding-left: calc(2 * var(--gap));}} -@media (max-width: 767px) {.t22.t22[data-variant="compact"][data-disabled]:not([data-pressed]):not([data-hovered]) {padding-top: calc(0.5 * var(--gap)); padding-right: calc(0.5 * var(--gap)); padding-bottom: calc(0.5 * var(--gap)); padding-left: calc(0.5 * var(--gap));}} -@media (max-width: 767px) {.t22.t22[data-pressed][data-disabled]:not([data-variant="compact"]):not([data-hovered]) {padding-top: calc(2 * var(--gap)); padding-right: calc(2 * var(--gap)); padding-bottom: calc(2 * var(--gap)); padding-left: calc(2 * var(--gap));}} -@media (max-width: 767px) {.t22.t22[data-variant="compact"][data-pressed][data-disabled]:not([data-hovered]) {padding-top: calc(0.5 * var(--gap)); padding-right: calc(0.5 * var(--gap)); padding-bottom: calc(0.5 * var(--gap)); padding-left: calc(0.5 * var(--gap));}} -@media (max-width: 767px) {.t22.t22[data-hovered]:not([data-variant="compact"]):not([data-pressed]):not([data-disabled]) {padding-top: calc(3 * var(--gap)); padding-right: calc(3 * var(--gap)); padding-bottom: calc(3 * var(--gap)); padding-left: calc(3 * var(--gap));}} -@media (max-width: 767px) {.t22.t22[data-variant="compact"][data-hovered]:not([data-pressed]):not([data-disabled]) {padding-top: calc(0.5 * var(--gap)); padding-right: calc(0.5 * var(--gap)); padding-bottom: calc(0.5 * var(--gap)); padding-left: calc(0.5 * var(--gap));}} -@media (max-width: 767px) {.t22.t22[data-pressed][data-hovered]:not([data-variant="compact"]):not([data-disabled]) {padding-top: var(--gap); padding-right: var(--gap); padding-bottom: var(--gap); padding-left: var(--gap);}} -@media (max-width: 767px) {.t22.t22[data-variant="compact"][data-pressed][data-hovered]:not([data-disabled]) {padding-top: calc(0.5 * var(--gap)); padding-right: calc(0.5 * var(--gap)); padding-bottom: calc(0.5 * var(--gap)); padding-left: calc(0.5 * var(--gap));}} -@media (max-width: 767px) {.t22.t22[data-disabled][data-hovered]:not([data-variant="compact"]):not([data-pressed]) {padding-top: calc(3 * var(--gap)); padding-right: calc(3 * var(--gap)); padding-bottom: calc(3 * var(--gap)); padding-left: calc(3 * var(--gap));}} -@media (max-width: 767px) {.t22.t22[data-variant="compact"][data-disabled][data-hovered]:not([data-pressed]) {padding-top: calc(0.5 * var(--gap)); padding-right: calc(0.5 * var(--gap)); padding-bottom: calc(0.5 * var(--gap)); padding-left: calc(0.5 * var(--gap));}} -@media (max-width: 767px) {.t22.t22[data-pressed][data-disabled][data-hovered]:not([data-variant="compact"]) {padding-top: calc(3 * var(--gap)); padding-right: calc(3 * var(--gap)); padding-bottom: calc(3 * var(--gap)); padding-left: calc(3 * var(--gap));}} -@media (max-width: 767px) {.t22.t22[data-variant="compact"][data-pressed][data-disabled][data-hovered] {padding-top: calc(0.5 * var(--gap)); padding-right: calc(0.5 * var(--gap)); padding-bottom: calc(0.5 * var(--gap)); padding-left: calc(0.5 * var(--gap));}} -@media (min-width: 1200px) {.t22.t22:not([data-hovered]):not([data-focused]):not([data-disabled]):not([data-expanded]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 1200px;}} -@media (min-width: 1200px) {.t22.t22[data-hovered]:not([data-focused]):not([data-disabled]):not([data-expanded]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 1300px;}} -@media (min-width: 1200px) {.t22.t22[data-focused]:not([data-hovered]):not([data-disabled]):not([data-expanded]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 1300px;}} -@media (min-width: 1200px) {.t22.t22[data-hovered][data-focused]:not([data-disabled]):not([data-expanded]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 1300px;}} -@media (min-width: 1200px) {.t22.t22[data-disabled]:not([data-hovered]):not([data-focused]):not([data-expanded]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 1200px;}} -@media (min-width: 1200px) {.t22.t22[data-hovered][data-disabled]:not([data-focused]):not([data-expanded]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 1200px;}} -@media (min-width: 1200px) {.t22.t22[data-focused][data-disabled]:not([data-hovered]):not([data-expanded]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 1200px;}} -@media (min-width: 1200px) {.t22.t22[data-hovered][data-focused][data-disabled]:not([data-expanded]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 1200px;}} -@media (min-width: 1200px) {.t22.t22[data-expanded]:not([data-hovered]):not([data-focused]):not([data-disabled]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 1400px;}} -@media (min-width: 1200px) {.t22.t22[data-hovered][data-expanded]:not([data-focused]):not([data-disabled]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 1300px;}} -@media (min-width: 1200px) {.t22.t22[data-focused][data-expanded]:not([data-hovered]):not([data-disabled]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 1300px;}} -@media (min-width: 1200px) {.t22.t22[data-hovered][data-focused][data-expanded]:not([data-disabled]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 1300px;}} -@media (min-width: 1200px) {.t22.t22[data-disabled][data-expanded]:not([data-hovered]):not([data-focused]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 1400px;}} -@media (min-width: 1200px) {.t22.t22[data-hovered][data-disabled][data-expanded]:not([data-focused]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 1400px;}} -@media (min-width: 1200px) {.t22.t22[data-focused][data-disabled][data-expanded]:not([data-hovered]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 1400px;}} -@media (min-width: 1200px) {.t22.t22[data-hovered][data-focused][data-disabled][data-expanded]:not([data-size="large"]) {width: auto; min-width: initial; max-width: 1400px;}} -@media (min-width: 1200px) {.t22.t22[data-size="large"]:not([data-hovered]):not([data-focused]):not([data-disabled]):not([data-expanded]) {width: auto; min-width: initial; max-width: 1400px;}} -@media (min-width: 1200px) {.t22.t22[data-hovered][data-size="large"]:not([data-focused]):not([data-disabled]):not([data-expanded]) {width: auto; min-width: initial; max-width: 1300px;}} -@media (min-width: 1200px) {.t22.t22[data-focused][data-size="large"]:not([data-hovered]):not([data-disabled]):not([data-expanded]) {width: auto; min-width: initial; max-width: 1300px;}} -@media (min-width: 1200px) {.t22.t22[data-hovered][data-focused][data-size="large"]:not([data-disabled]):not([data-expanded]) {width: auto; min-width: initial; max-width: 1300px;}} -@media (min-width: 1200px) {.t22.t22[data-disabled][data-size="large"]:not([data-hovered]):not([data-focused]):not([data-expanded]) {width: auto; min-width: initial; max-width: 1400px;}} -@media (min-width: 1200px) {.t22.t22[data-hovered][data-disabled][data-size="large"]:not([data-focused]):not([data-expanded]) {width: auto; min-width: initial; max-width: 1400px;}} -@media (min-width: 1200px) {.t22.t22[data-focused][data-disabled][data-size="large"]:not([data-hovered]):not([data-expanded]) {width: auto; min-width: initial; max-width: 1400px;}} -@media (min-width: 1200px) {.t22.t22[data-hovered][data-focused][data-disabled][data-size="large"]:not([data-expanded]) {width: auto; min-width: initial; max-width: 1400px;}} -@media (min-width: 1200px) {.t22.t22[data-expanded][data-size="large"]:not([data-hovered]):not([data-focused]):not([data-disabled]) {width: auto; min-width: initial; max-width: 1400px;}} -@media (min-width: 1200px) {.t22.t22[data-hovered][data-expanded][data-size="large"]:not([data-focused]):not([data-disabled]) {width: auto; min-width: initial; max-width: 1300px;}} -@media (min-width: 1200px) {.t22.t22[data-focused][data-expanded][data-size="large"]:not([data-hovered]):not([data-disabled]) {width: auto; min-width: initial; max-width: 1300px;}} -@media (min-width: 1200px) {.t22.t22[data-hovered][data-focused][data-expanded][data-size="large"]:not([data-disabled]) {width: auto; min-width: initial; max-width: 1300px;}} -@media (min-width: 1200px) {.t22.t22[data-disabled][data-expanded][data-size="large"]:not([data-hovered]):not([data-focused]) {width: auto; min-width: initial; max-width: 1400px;}} -@media (min-width: 1200px) {.t22.t22[data-hovered][data-disabled][data-expanded][data-size="large"]:not([data-focused]) {width: auto; min-width: initial; max-width: 1400px;}} -@media (min-width: 1200px) {.t22.t22[data-focused][data-disabled][data-expanded][data-size="large"]:not([data-hovered]) {width: auto; min-width: initial; max-width: 1400px;}} -@media (min-width: 1200px) {.t22.t22[data-hovered][data-focused][data-disabled][data-expanded][data-size="large"] {width: auto; min-width: initial; max-width: 1400px;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22:not([data-hovered]):not([data-focused]):not([data-disabled]):not([data-expanded]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 800px;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-hovered]:not([data-focused]):not([data-disabled]):not([data-expanded]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 900px;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-focused]:not([data-hovered]):not([data-disabled]):not([data-expanded]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 900px;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-hovered][data-focused]:not([data-disabled]):not([data-expanded]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 900px;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-disabled]:not([data-hovered]):not([data-focused]):not([data-expanded]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 800px;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-hovered][data-disabled]:not([data-focused]):not([data-expanded]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 800px;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-focused][data-disabled]:not([data-hovered]):not([data-expanded]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 800px;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-hovered][data-focused][data-disabled]:not([data-expanded]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 800px;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-expanded]:not([data-hovered]):not([data-focused]):not([data-disabled]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 1000px;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-hovered][data-expanded]:not([data-focused]):not([data-disabled]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 900px;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-focused][data-expanded]:not([data-hovered]):not([data-disabled]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 900px;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-hovered][data-focused][data-expanded]:not([data-disabled]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 900px;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-disabled][data-expanded]:not([data-hovered]):not([data-focused]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 1000px;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-hovered][data-disabled][data-expanded]:not([data-focused]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 1000px;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-focused][data-disabled][data-expanded]:not([data-hovered]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 1000px;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-hovered][data-focused][data-disabled][data-expanded]:not([data-size="large"]) {width: auto; min-width: initial; max-width: 1000px;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-size="large"]:not([data-hovered]):not([data-focused]):not([data-disabled]):not([data-expanded]) {width: auto; min-width: initial; max-width: 1000px;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-hovered][data-size="large"]:not([data-focused]):not([data-disabled]):not([data-expanded]) {width: auto; min-width: initial; max-width: 900px;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-focused][data-size="large"]:not([data-hovered]):not([data-disabled]):not([data-expanded]) {width: auto; min-width: initial; max-width: 900px;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-hovered][data-focused][data-size="large"]:not([data-disabled]):not([data-expanded]) {width: auto; min-width: initial; max-width: 900px;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-disabled][data-size="large"]:not([data-hovered]):not([data-focused]):not([data-expanded]) {width: auto; min-width: initial; max-width: 1000px;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-hovered][data-disabled][data-size="large"]:not([data-focused]):not([data-expanded]) {width: auto; min-width: initial; max-width: 1000px;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-focused][data-disabled][data-size="large"]:not([data-hovered]):not([data-expanded]) {width: auto; min-width: initial; max-width: 1000px;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-hovered][data-focused][data-disabled][data-size="large"]:not([data-expanded]) {width: auto; min-width: initial; max-width: 1000px;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-expanded][data-size="large"]:not([data-hovered]):not([data-focused]):not([data-disabled]) {width: auto; min-width: initial; max-width: 1000px;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-hovered][data-expanded][data-size="large"]:not([data-focused]):not([data-disabled]) {width: auto; min-width: initial; max-width: 900px;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-focused][data-expanded][data-size="large"]:not([data-hovered]):not([data-disabled]) {width: auto; min-width: initial; max-width: 900px;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-hovered][data-focused][data-expanded][data-size="large"]:not([data-disabled]) {width: auto; min-width: initial; max-width: 900px;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-disabled][data-expanded][data-size="large"]:not([data-hovered]):not([data-focused]) {width: auto; min-width: initial; max-width: 1000px;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-hovered][data-disabled][data-expanded][data-size="large"]:not([data-focused]) {width: auto; min-width: initial; max-width: 1000px;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-focused][data-disabled][data-expanded][data-size="large"]:not([data-hovered]) {width: auto; min-width: initial; max-width: 1000px;}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-hovered][data-focused][data-disabled][data-expanded][data-size="large"] {width: auto; min-width: initial; max-width: 1000px;}} -@media (max-width: 767px) {.t22.t22:not([data-hovered]):not([data-focused]):not([data-disabled]):not([data-expanded]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 100%;}} -@media (max-width: 767px) {.t22.t22[data-hovered]:not([data-focused]):not([data-disabled]):not([data-expanded]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 100%;}} -@media (max-width: 767px) {.t22.t22[data-focused]:not([data-hovered]):not([data-disabled]):not([data-expanded]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 100%;}} -@media (max-width: 767px) {.t22.t22[data-hovered][data-focused]:not([data-disabled]):not([data-expanded]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 100%;}} -@media (max-width: 767px) {.t22.t22[data-disabled]:not([data-hovered]):not([data-focused]):not([data-expanded]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 100%;}} -@media (max-width: 767px) {.t22.t22[data-hovered][data-disabled]:not([data-focused]):not([data-expanded]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 100%;}} -@media (max-width: 767px) {.t22.t22[data-focused][data-disabled]:not([data-hovered]):not([data-expanded]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 100%;}} -@media (max-width: 767px) {.t22.t22[data-hovered][data-focused][data-disabled]:not([data-expanded]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 100%;}} -@media (max-width: 767px) {.t22.t22[data-expanded]:not([data-hovered]):not([data-focused]):not([data-disabled]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 100%;}} -@media (max-width: 767px) {.t22.t22[data-hovered][data-expanded]:not([data-focused]):not([data-disabled]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 100%;}} -@media (max-width: 767px) {.t22.t22[data-focused][data-expanded]:not([data-hovered]):not([data-disabled]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 100%;}} -@media (max-width: 767px) {.t22.t22[data-hovered][data-focused][data-expanded]:not([data-disabled]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 100%;}} -@media (max-width: 767px) {.t22.t22[data-disabled][data-expanded]:not([data-hovered]):not([data-focused]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 100%;}} -@media (max-width: 767px) {.t22.t22[data-hovered][data-disabled][data-expanded]:not([data-focused]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 100%;}} -@media (max-width: 767px) {.t22.t22[data-focused][data-disabled][data-expanded]:not([data-hovered]):not([data-size="large"]) {width: auto; min-width: initial; max-width: 100%;}} -@media (max-width: 767px) {.t22.t22[data-hovered][data-focused][data-disabled][data-expanded]:not([data-size="large"]) {width: auto; min-width: initial; max-width: 100%;}} -@media (max-width: 767px) {.t22.t22[data-size="large"]:not([data-hovered]):not([data-focused]):not([data-disabled]):not([data-expanded]) {width: auto; min-width: initial; max-width: 100%;}} -@media (max-width: 767px) {.t22.t22[data-hovered][data-size="large"]:not([data-focused]):not([data-disabled]):not([data-expanded]) {width: auto; min-width: initial; max-width: 100%;}} -@media (max-width: 767px) {.t22.t22[data-focused][data-size="large"]:not([data-hovered]):not([data-disabled]):not([data-expanded]) {width: auto; min-width: initial; max-width: 100%;}} -@media (max-width: 767px) {.t22.t22[data-hovered][data-focused][data-size="large"]:not([data-disabled]):not([data-expanded]) {width: auto; min-width: initial; max-width: 100%;}} -@media (max-width: 767px) {.t22.t22[data-disabled][data-size="large"]:not([data-hovered]):not([data-focused]):not([data-expanded]) {width: auto; min-width: initial; max-width: 100%;}} -@media (max-width: 767px) {.t22.t22[data-hovered][data-disabled][data-size="large"]:not([data-focused]):not([data-expanded]) {width: auto; min-width: initial; max-width: 100%;}} -@media (max-width: 767px) {.t22.t22[data-focused][data-disabled][data-size="large"]:not([data-hovered]):not([data-expanded]) {width: auto; min-width: initial; max-width: 100%;}} -@media (max-width: 767px) {.t22.t22[data-hovered][data-focused][data-disabled][data-size="large"]:not([data-expanded]) {width: auto; min-width: initial; max-width: 100%;}} -@media (max-width: 767px) {.t22.t22[data-expanded][data-size="large"]:not([data-hovered]):not([data-focused]):not([data-disabled]) {width: auto; min-width: initial; max-width: 100%;}} -@media (max-width: 767px) {.t22.t22[data-hovered][data-expanded][data-size="large"]:not([data-focused]):not([data-disabled]) {width: auto; min-width: initial; max-width: 100%;}} -@media (max-width: 767px) {.t22.t22[data-focused][data-expanded][data-size="large"]:not([data-hovered]):not([data-disabled]) {width: auto; min-width: initial; max-width: 100%;}} -@media (max-width: 767px) {.t22.t22[data-hovered][data-focused][data-expanded][data-size="large"]:not([data-disabled]) {width: auto; min-width: initial; max-width: 100%;}} -@media (max-width: 767px) {.t22.t22[data-disabled][data-expanded][data-size="large"]:not([data-hovered]):not([data-focused]) {width: auto; min-width: initial; max-width: 100%;}} -@media (max-width: 767px) {.t22.t22[data-hovered][data-disabled][data-expanded][data-size="large"]:not([data-focused]) {width: auto; min-width: initial; max-width: 100%;}} -@media (max-width: 767px) {.t22.t22[data-focused][data-disabled][data-expanded][data-size="large"]:not([data-hovered]) {width: auto; min-width: initial; max-width: 100%;}} -@media (max-width: 767px) {.t22.t22[data-hovered][data-focused][data-disabled][data-expanded][data-size="large"] {width: auto; min-width: initial; max-width: 100%;}} -.t22.t22:not([data-variant="success"]):not([data-disabled]):not([data-variant="danger"]):not([data-hovered]):not([data-pressed]) {background-color: var(--surface-color);} -.t22.t22:not([data-variant="success"]):not([data-disabled]):not([data-variant="danger"]):not([data-hovered]):not([data-pressed])>* {--context-fill-color: var(--surface-color); --context-fill-color-rgb: var(--surface-color-rgb);} -.t22.t22[data-variant="success"]:not([data-disabled]):not([data-hovered]):not([data-pressed]) {background-color: var(--success-color);} -.t22.t22[data-variant="success"]:not([data-disabled]):not([data-hovered]):not([data-pressed])>* {--context-fill-color: var(--success-color); --context-fill-color-rgb: var(--success-color-rgb);} -.t22.t22[data-disabled]:not([data-variant="success"]):not([data-variant="danger"]):not([data-hovered]):not([data-pressed]) {background-color: var(--surface-disabled-color);} -.t22.t22[data-disabled]:not([data-variant="success"]):not([data-variant="danger"]):not([data-hovered]):not([data-pressed])>* {--context-fill-color: var(--surface-disabled-color); --context-fill-color-rgb: var(--surface-disabled-color-rgb);} -.t22.t22[data-variant="success"][data-disabled]:not([data-hovered]):not([data-pressed]) {background-color: var(--surface-disabled-color);} -.t22.t22[data-variant="success"][data-disabled]:not([data-hovered]):not([data-pressed])>* {--context-fill-color: var(--surface-disabled-color); --context-fill-color-rgb: var(--surface-disabled-color-rgb);} -.t22.t22[data-variant="danger"]:not([data-disabled]):not([data-hovered]):not([data-pressed]) {background-color: var(--surface-color);} -.t22.t22[data-variant="danger"]:not([data-disabled]):not([data-hovered]):not([data-pressed])>* {--context-fill-color: var(--surface-color); --context-fill-color-rgb: var(--surface-color-rgb);} -.t22.t22[data-disabled][data-variant="danger"]:not([data-hovered]):not([data-pressed]) {background-color: var(--surface-disabled-color);} -.t22.t22[data-disabled][data-variant="danger"]:not([data-hovered]):not([data-pressed])>* {--context-fill-color: var(--surface-disabled-color); --context-fill-color-rgb: var(--surface-disabled-color-rgb);} -.t22.t22[data-hovered]:not([data-variant="success"]):not([data-disabled]):not([data-variant="danger"]):not([data-pressed]) {background-color: var(--surface-hover-color);} -.t22.t22[data-hovered]:not([data-variant="success"]):not([data-disabled]):not([data-variant="danger"]):not([data-pressed])>* {--context-fill-color: var(--surface-hover-color); --context-fill-color-rgb: var(--surface-hover-color-rgb);} -.t22.t22[data-variant="success"][data-hovered]:not([data-disabled]):not([data-pressed]) {background-color: var(--success-color);} -.t22.t22[data-variant="success"][data-hovered]:not([data-disabled]):not([data-pressed])>* {--context-fill-color: var(--success-color); --context-fill-color-rgb: var(--success-color-rgb);} -.t22.t22[data-disabled][data-hovered]:not([data-variant="success"]):not([data-variant="danger"]):not([data-pressed]) {background-color: var(--surface-disabled-color);} -.t22.t22[data-disabled][data-hovered]:not([data-variant="success"]):not([data-variant="danger"]):not([data-pressed])>* {--context-fill-color: var(--surface-disabled-color); --context-fill-color-rgb: var(--surface-disabled-color-rgb);} -.t22.t22[data-variant="success"][data-disabled][data-hovered]:not([data-pressed]) {background-color: var(--surface-disabled-color);} -.t22.t22[data-variant="success"][data-disabled][data-hovered]:not([data-pressed])>* {--context-fill-color: var(--surface-disabled-color); --context-fill-color-rgb: var(--surface-disabled-color-rgb);} -.t22.t22[data-variant="danger"][data-hovered]:not([data-disabled]):not([data-pressed]) {background-color: var(--danger-hover-color);} -.t22.t22[data-variant="danger"][data-hovered]:not([data-disabled]):not([data-pressed])>* {--context-fill-color: var(--danger-hover-color); --context-fill-color-rgb: var(--danger-hover-color-rgb);} -.t22.t22[data-disabled][data-variant="danger"][data-hovered]:not([data-pressed]) {background-color: var(--danger-hover-color);} -.t22.t22[data-disabled][data-variant="danger"][data-hovered]:not([data-pressed])>* {--context-fill-color: var(--danger-hover-color); --context-fill-color-rgb: var(--danger-hover-color-rgb);} -.t22.t22[data-pressed]:not([data-variant="success"]):not([data-disabled]):not([data-variant="danger"]):not([data-hovered]) {background-color: var(--surface-pressed-color);} -.t22.t22[data-pressed]:not([data-variant="success"]):not([data-disabled]):not([data-variant="danger"]):not([data-hovered])>* {--context-fill-color: var(--surface-pressed-color); --context-fill-color-rgb: var(--surface-pressed-color-rgb);} -.t22.t22[data-variant="success"][data-pressed]:not([data-disabled]):not([data-hovered]) {background-color: var(--success-color);} -.t22.t22[data-variant="success"][data-pressed]:not([data-disabled]):not([data-hovered])>* {--context-fill-color: var(--success-color); --context-fill-color-rgb: var(--success-color-rgb);} -.t22.t22[data-disabled][data-pressed]:not([data-variant="success"]):not([data-variant="danger"]):not([data-hovered]) {background-color: var(--surface-disabled-color);} -.t22.t22[data-disabled][data-pressed]:not([data-variant="success"]):not([data-variant="danger"]):not([data-hovered])>* {--context-fill-color: var(--surface-disabled-color); --context-fill-color-rgb: var(--surface-disabled-color-rgb);} -.t22.t22[data-variant="success"][data-disabled][data-pressed]:not([data-hovered]) {background-color: var(--surface-disabled-color);} -.t22.t22[data-variant="success"][data-disabled][data-pressed]:not([data-hovered])>* {--context-fill-color: var(--surface-disabled-color); --context-fill-color-rgb: var(--surface-disabled-color-rgb);} -.t22.t22[data-variant="danger"][data-pressed]:not([data-disabled]):not([data-hovered]) {background-color: var(--surface-pressed-color);} -.t22.t22[data-variant="danger"][data-pressed]:not([data-disabled]):not([data-hovered])>* {--context-fill-color: var(--surface-pressed-color); --context-fill-color-rgb: var(--surface-pressed-color-rgb);} -.t22.t22[data-disabled][data-variant="danger"][data-pressed]:not([data-hovered]) {background-color: var(--surface-disabled-color);} -.t22.t22[data-disabled][data-variant="danger"][data-pressed]:not([data-hovered])>* {--context-fill-color: var(--surface-disabled-color); --context-fill-color-rgb: var(--surface-disabled-color-rgb);} -.t22.t22[data-hovered][data-pressed]:not([data-variant="success"]):not([data-disabled]):not([data-variant="danger"]) {background-color: var(--surface-pressed-color);} -.t22.t22[data-hovered][data-pressed]:not([data-variant="success"]):not([data-disabled]):not([data-variant="danger"])>* {--context-fill-color: var(--surface-pressed-color); --context-fill-color-rgb: var(--surface-pressed-color-rgb);} -.t22.t22[data-variant="success"][data-hovered][data-pressed]:not([data-disabled]) {background-color: var(--success-color);} -.t22.t22[data-variant="success"][data-hovered][data-pressed]:not([data-disabled])>* {--context-fill-color: var(--success-color); --context-fill-color-rgb: var(--success-color-rgb);} -.t22.t22[data-disabled][data-hovered][data-pressed]:not([data-variant="success"]):not([data-variant="danger"]) {background-color: var(--surface-disabled-color);} -.t22.t22[data-disabled][data-hovered][data-pressed]:not([data-variant="success"]):not([data-variant="danger"])>* {--context-fill-color: var(--surface-disabled-color); --context-fill-color-rgb: var(--surface-disabled-color-rgb);} -.t22.t22[data-variant="success"][data-disabled][data-hovered][data-pressed] {background-color: var(--surface-disabled-color);} -.t22.t22[data-variant="success"][data-disabled][data-hovered][data-pressed]>* {--context-fill-color: var(--surface-disabled-color); --context-fill-color-rgb: var(--surface-disabled-color-rgb);} -.t22.t22[data-variant="danger"][data-hovered][data-pressed]:not([data-disabled]) {background-color: var(--danger-hover-color);} -.t22.t22[data-variant="danger"][data-hovered][data-pressed]:not([data-disabled])>* {--context-fill-color: var(--danger-hover-color); --context-fill-color-rgb: var(--danger-hover-color-rgb);} -.t22.t22[data-disabled][data-variant="danger"][data-hovered][data-pressed] {background-color: var(--danger-hover-color);} -.t22.t22[data-disabled][data-variant="danger"][data-hovered][data-pressed]>* {--context-fill-color: var(--danger-hover-color); --context-fill-color-rgb: var(--danger-hover-color-rgb);} -@media (min-width: 1200px) {.t22.t22:not([data-variant="borderless"]):not([data-hovered]):not([data-error]):not([data-focused]) {border: calc(2 * var(--border-width)) solid var(--border-color);}} -@media (min-width: 1200px) {.t22.t22[data-variant="borderless"]:not([data-hovered]):not([data-error]):not([data-focused]) {border: calc(2 * var(--border-width)) solid var(--border-color);}} -@media (min-width: 1200px) {.t22.t22[data-hovered]:not([data-variant="borderless"]):not([data-error]):not([data-focused]) {border: calc(2 * var(--border-width)) solid var(--border-hover-color);}} -@media (min-width: 1200px) {.t22.t22[data-variant="borderless"][data-hovered]:not([data-error]):not([data-focused]) {border: calc(2 * var(--border-width)) solid var(--border-color);}} -@media (min-width: 1200px) {.t22.t22[data-error]:not([data-variant="borderless"]):not([data-hovered]):not([data-focused]) {border: calc(2 * var(--border-width)) solid var(--border-color);}} -@media (min-width: 1200px) {.t22.t22[data-variant="borderless"][data-error]:not([data-hovered]):not([data-focused]) {border: calc(2 * var(--border-width)) solid var(--border-color);}} -@media (min-width: 1200px) {.t22.t22[data-hovered][data-error]:not([data-variant="borderless"]):not([data-focused]) {border: calc(2 * var(--border-width)) solid var(--border-hover-color);}} -@media (min-width: 1200px) {.t22.t22[data-variant="borderless"][data-hovered][data-error]:not([data-focused]) {border: calc(2 * var(--border-width)) solid var(--border-color);}} -@media (min-width: 1200px) {.t22.t22[data-focused]:not([data-variant="borderless"]):not([data-hovered]):not([data-error]) {border: calc(3 * var(--border-width)) solid var(--primary-color);}} -@media (min-width: 1200px) {.t22.t22[data-variant="borderless"][data-focused]:not([data-hovered]):not([data-error]) {border: calc(3 * var(--border-width)) solid var(--primary-color);}} -@media (min-width: 1200px) {.t22.t22[data-hovered][data-focused]:not([data-variant="borderless"]):not([data-error]) {border: calc(2 * var(--border-width)) solid var(--border-hover-color);}} -@media (min-width: 1200px) {.t22.t22[data-variant="borderless"][data-hovered][data-focused]:not([data-error]) {border: calc(3 * var(--border-width)) solid var(--primary-color);}} -@media (min-width: 1200px) {.t22.t22[data-error][data-focused]:not([data-variant="borderless"]):not([data-hovered]) {border: calc(3 * var(--border-width)) solid var(--danger-color);}} -@media (min-width: 1200px) {.t22.t22[data-variant="borderless"][data-error][data-focused]:not([data-hovered]) {border: calc(3 * var(--border-width)) solid var(--danger-color);}} -@media (min-width: 1200px) {.t22.t22[data-hovered][data-error][data-focused]:not([data-variant="borderless"]) {border: calc(2 * var(--border-width)) solid var(--border-hover-color);}} -@media (min-width: 1200px) {.t22.t22[data-variant="borderless"][data-hovered][data-error][data-focused] {border: calc(3 * var(--border-width)) solid var(--danger-color);}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22:not([data-variant="borderless"]):not([data-hovered]):not([data-error]):not([data-focused]) {border: var(--border-width) solid var(--border-color);}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-variant="borderless"]:not([data-hovered]):not([data-error]):not([data-focused]) {border: var(--border-width) solid var(--border-color);}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-hovered]:not([data-variant="borderless"]):not([data-error]):not([data-focused]) {border: var(--border-width) solid var(--border-hover-color);}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-variant="borderless"][data-hovered]:not([data-error]):not([data-focused]) {border: var(--border-width) solid var(--border-color);}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-error]:not([data-variant="borderless"]):not([data-hovered]):not([data-focused]) {border: var(--border-width) solid var(--border-color);}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-variant="borderless"][data-error]:not([data-hovered]):not([data-focused]) {border: var(--border-width) solid var(--border-color);}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-hovered][data-error]:not([data-variant="borderless"]):not([data-focused]) {border: var(--border-width) solid var(--border-hover-color);}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-variant="borderless"][data-hovered][data-error]:not([data-focused]) {border: var(--border-width) solid var(--border-color);}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-focused]:not([data-variant="borderless"]):not([data-hovered]):not([data-error]) {border: calc(2 * var(--border-width)) solid var(--primary-color);}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-variant="borderless"][data-focused]:not([data-hovered]):not([data-error]) {border: calc(2 * var(--border-width)) solid var(--primary-color);}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-hovered][data-focused]:not([data-variant="borderless"]):not([data-error]) {border: var(--border-width) solid var(--border-hover-color);}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-variant="borderless"][data-hovered][data-focused]:not([data-error]) {border: calc(2 * var(--border-width)) solid var(--primary-color);}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-error][data-focused]:not([data-variant="borderless"]):not([data-hovered]) {border: calc(2 * var(--border-width)) solid var(--danger-color);}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-variant="borderless"][data-error][data-focused]:not([data-hovered]) {border: calc(2 * var(--border-width)) solid var(--danger-color);}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-hovered][data-error][data-focused]:not([data-variant="borderless"]) {border: var(--border-width) solid var(--border-hover-color);}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22[data-variant="borderless"][data-hovered][data-error][data-focused] {border: calc(2 * var(--border-width)) solid var(--danger-color);}} -@media (max-width: 767px) {.t22.t22:not([data-variant="borderless"]):not([data-hovered]):not([data-error]):not([data-focused]) {border: var(--border-width) none var(--border-color);}} -@media (max-width: 767px) {.t22.t22[data-variant="borderless"]:not([data-hovered]):not([data-error]):not([data-focused]) {border: var(--border-width) none var(--border-color);}} -@media (max-width: 767px) {.t22.t22[data-hovered]:not([data-variant="borderless"]):not([data-error]):not([data-focused]) {border: var(--border-width) solid var(--border-hover-color);}} -@media (max-width: 767px) {.t22.t22[data-variant="borderless"][data-hovered]:not([data-error]):not([data-focused]) {border: var(--border-width) none var(--border-color);}} -@media (max-width: 767px) {.t22.t22[data-error]:not([data-variant="borderless"]):not([data-hovered]):not([data-focused]) {border: var(--border-width) none var(--border-color);}} -@media (max-width: 767px) {.t22.t22[data-variant="borderless"][data-error]:not([data-hovered]):not([data-focused]) {border: var(--border-width) none var(--border-color);}} -@media (max-width: 767px) {.t22.t22[data-hovered][data-error]:not([data-variant="borderless"]):not([data-focused]) {border: var(--border-width) solid var(--border-hover-color);}} -@media (max-width: 767px) {.t22.t22[data-variant="borderless"][data-hovered][data-error]:not([data-focused]) {border: var(--border-width) none var(--border-color);}} -@media (max-width: 767px) {.t22.t22[data-focused]:not([data-variant="borderless"]):not([data-hovered]):not([data-error]) {border: var(--border-width) solid var(--primary-color);}} -@media (max-width: 767px) {.t22.t22[data-variant="borderless"][data-focused]:not([data-hovered]):not([data-error]) {border: var(--border-width) solid var(--primary-color);}} -@media (max-width: 767px) {.t22.t22[data-hovered][data-focused]:not([data-variant="borderless"]):not([data-error]) {border: var(--border-width) solid var(--border-hover-color);}} -@media (max-width: 767px) {.t22.t22[data-variant="borderless"][data-hovered][data-focused]:not([data-error]) {border: var(--border-width) solid var(--primary-color);}} -@media (max-width: 767px) {.t22.t22[data-error][data-focused]:not([data-variant="borderless"]):not([data-hovered]) {border: var(--border-width) solid var(--danger-color);}} -@media (max-width: 767px) {.t22.t22[data-variant="borderless"][data-error][data-focused]:not([data-hovered]) {border: var(--border-width) solid var(--danger-color);}} -@media (max-width: 767px) {.t22.t22[data-hovered][data-error][data-focused]:not([data-variant="borderless"]) {border: var(--border-width) solid var(--border-hover-color);}} -@media (max-width: 767px) {.t22.t22[data-variant="borderless"][data-hovered][data-error][data-focused] {border: var(--border-width) solid var(--danger-color);}} -@media (min-width: 1200px) {.t22.t22>* {--context-radius: calc(2 * var(--radius));}} -@media (min-width: 768px) and (max-width: 1199px) {.t22.t22>* {--context-radius: var(--radius);}} -@media (max-width: 767px) {.t22.t22>* {--context-radius: calc(0.5 * var(--radius));}}" -`; - -exports[`tasty() API should handle state-map-of-arrays pattern 1`] = ` -".t20.t20 {display: block;} -@media (min-width: 1200px) {.t20.t20:not([data-variant="compact"]):not([data-hovered]) {padding-top: calc(4 * var(--gap)); padding-right: calc(4 * var(--gap)); padding-bottom: calc(4 * var(--gap)); padding-left: calc(4 * var(--gap));}} -@media (min-width: 1200px) {.t20.t20[data-variant="compact"]:not([data-hovered]) {padding-top: calc(2 * var(--gap)); padding-right: calc(2 * var(--gap)); padding-bottom: calc(2 * var(--gap)); padding-left: calc(2 * var(--gap));}} -@media (min-width: 1200px) {.t20.t20[data-hovered]:not([data-variant="compact"]) {padding-top: calc(6 * var(--gap)); padding-right: calc(6 * var(--gap)); padding-bottom: calc(6 * var(--gap)); padding-left: calc(6 * var(--gap));}} -@media (min-width: 1200px) {.t20.t20[data-variant="compact"][data-hovered] {padding-top: calc(2 * var(--gap)); padding-right: calc(2 * var(--gap)); padding-bottom: calc(2 * var(--gap)); padding-left: calc(2 * var(--gap));}} -@media (min-width: 768px) and (max-width: 1199px) {.t20.t20:not([data-variant="compact"]):not([data-hovered]) {padding-top: calc(2 * var(--gap)); padding-right: calc(2 * var(--gap)); padding-bottom: calc(2 * var(--gap)); padding-left: calc(2 * var(--gap));}} -@media (min-width: 768px) and (max-width: 1199px) {.t20.t20[data-variant="compact"]:not([data-hovered]) {padding-top: var(--gap); padding-right: var(--gap); padding-bottom: var(--gap); padding-left: var(--gap);}} -@media (min-width: 768px) and (max-width: 1199px) {.t20.t20[data-hovered]:not([data-variant="compact"]) {padding-top: calc(3 * var(--gap)); padding-right: calc(3 * var(--gap)); padding-bottom: calc(3 * var(--gap)); padding-left: calc(3 * var(--gap));}} -@media (min-width: 768px) and (max-width: 1199px) {.t20.t20[data-variant="compact"][data-hovered] {padding-top: var(--gap); padding-right: var(--gap); padding-bottom: var(--gap); padding-left: var(--gap);}} -@media (max-width: 767px) {.t20.t20:not([data-variant="compact"]):not([data-hovered]) {padding-top: var(--gap); padding-right: var(--gap); padding-bottom: var(--gap); padding-left: var(--gap);}} -@media (max-width: 767px) {.t20.t20[data-variant="compact"]:not([data-hovered]) {padding-top: calc(0.5 * var(--gap)); padding-right: calc(0.5 * var(--gap)); padding-bottom: calc(0.5 * var(--gap)); padding-left: calc(0.5 * var(--gap));}} -@media (max-width: 767px) {.t20.t20[data-hovered]:not([data-variant="compact"]) {padding-top: calc(1.5 * var(--gap)); padding-right: calc(1.5 * var(--gap)); padding-bottom: calc(1.5 * var(--gap)); padding-left: calc(1.5 * var(--gap));}} -@media (max-width: 767px) {.t20.t20[data-variant="compact"][data-hovered] {padding-top: calc(0.5 * var(--gap)); padding-right: calc(0.5 * var(--gap)); padding-bottom: calc(0.5 * var(--gap)); padding-left: calc(0.5 * var(--gap));}} -@media (min-width: 1200px) {.t20.t20:not([data-error]):not([data-focused]) {border: calc(2 * var(--border-width)) solid var(--border-color);}} -@media (min-width: 1200px) {.t20.t20[data-error]:not([data-focused]) {border: calc(2 * var(--border-width)) solid var(--border-color);}} -@media (min-width: 1200px) {.t20.t20[data-focused]:not([data-error]) {border: calc(3 * var(--border-width)) solid var(--primary-color);}} -@media (min-width: 1200px) {.t20.t20[data-error][data-focused] {border: calc(3 * var(--border-width)) solid var(--danger-color);}} -@media (min-width: 768px) and (max-width: 1199px) {.t20.t20:not([data-error]):not([data-focused]) {border: var(--border-width) solid var(--border-color);}} -@media (min-width: 768px) and (max-width: 1199px) {.t20.t20[data-error]:not([data-focused]) {border: var(--border-width) solid var(--border-color);}} -@media (min-width: 768px) and (max-width: 1199px) {.t20.t20[data-focused]:not([data-error]) {border: calc(2 * var(--border-width)) solid var(--primary-color);}} -@media (min-width: 768px) and (max-width: 1199px) {.t20.t20[data-error][data-focused] {border: calc(2 * var(--border-width)) solid var(--danger-color);}} -@media (max-width: 767px) {.t20.t20:not([data-error]):not([data-focused]) {border: var(--border-width) none var(--border-color);}} -@media (max-width: 767px) {.t20.t20[data-error]:not([data-focused]) {border: var(--border-width) none var(--border-color);}} -@media (max-width: 767px) {.t20.t20[data-focused]:not([data-error]) {border: var(--border-width) solid var(--primary-color);}} -@media (max-width: 767px) {.t20.t20[data-error][data-focused] {border: var(--border-width) solid var(--danger-color);}}" -`; - exports[`tasty() API should merge element styles 1`] = ` -".t12.t12:not([data-modified]) [data-element="Element"] {color: var(--dark-color); --current-color: var(--dark-color, dark); --current-color-rgb: var(--dark-color-rgb);} -.t12.t12[data-modified] [data-element="Element"] {color: var(--purple-color); --current-color: var(--purple-color, purple); --current-color-rgb: var(--purple-color-rgb);} -.t12.t12 [data-element="Element"] {background-color: var(--black-color);} -.t12.t12 [data-element="Element"]>* {--context-fill-color: var(--black-color); --context-fill-color-rgb: var(--black-color-rgb);}" +".t11.t11:not([data-modified]) [data-element="Element"] {color: var(--dark-color); --current-color: var(--dark-color, dark); --current-color-rgb: var(--dark-color-rgb);} +.t11.t11[data-modified] [data-element="Element"] {color: var(--purple-color); --current-color: var(--purple-color, purple); --current-color-rgb: var(--purple-color-rgb);} +.t11.t11 [data-element="Element"] {background-color: var(--black-color);} +.t11.t11 [data-element="Element"]>* {--context-fill-color: var(--black-color); --context-fill-color-rgb: var(--black-color-rgb);}" `; exports[`tasty() API should merge styles 1`] = ` @@ -387,72 +41,34 @@ exports[`tasty() API should merge styles in custom prop 1`] = ` `; exports[`tasty() API should optimize attribute selectors 1`] = ` -".t16.t16 {display: block;} -.t16.t16:not([data-size="large"]):not([data-size="medium"]) {padding-top: var(--gap);} -.t16.t16[data-size="large"] {padding-top: calc(3 * var(--gap));} -.t16.t16[data-size="medium"] {padding-top: calc(2 * var(--gap));}" +".t15.t15 {display: block;} +.t15.t15:not([data-size="large"]):not([data-size="medium"]) {padding-top: var(--gap);} +.t15.t15[data-size="large"] {padding-top: calc(3 * var(--gap));} +.t15.t15[data-size="medium"] {padding-top: calc(2 * var(--gap));}" `; exports[`tasty() API should optimize attribute selectors 2`] = ` -".t17.t17 {display: block;} -.t17.t17:not([data-size="large"]):not([data-size="medium"]):not([data-selected]) {padding-top: var(--gap);} -.t17.t17[data-size="large"]:not([data-selected]) {padding-top: calc(3 * var(--gap));} -.t17.t17[data-size="medium"]:not([data-selected]) {padding-top: var(--gap);} -.t17.t17[data-selected]:not([data-size="large"]):not([data-size="medium"]) {padding-top: var(--gap);} -.t17.t17[data-size="large"][data-selected] {padding-top: calc(3 * var(--gap));} -.t17.t17[data-size="medium"][data-selected] {padding-top: calc(2 * var(--gap));}" +".t16.t16 {display: block;} +.t16.t16:not([data-size="large"]):not([data-size="medium"]):not([data-selected]) {padding-top: var(--gap);} +.t16.t16[data-size="large"]:not([data-selected]) {padding-top: calc(3 * var(--gap));} +.t16.t16[data-size="medium"]:not([data-selected]) {padding-top: var(--gap);} +.t16.t16[data-selected]:not([data-size="large"]):not([data-size="medium"]) {padding-top: var(--gap);} +.t16.t16[data-size="large"][data-selected] {padding-top: calc(3 * var(--gap));} +.t16.t16[data-size="medium"][data-selected] {padding-top: calc(2 * var(--gap));}" `; exports[`tasty() API should optimize attribute selectors 3`] = ` -".t18.t18 {display: block;} -.t18.t18:not([data-size="large"]):not([data-selected]):not([data-size="medium"]) {padding-top: var(--gap);} -.t18.t18[data-size="large"]:not([data-selected]) {padding-top: var(--gap);} -.t18.t18[data-selected]:not([data-size="large"]):not([data-size="medium"]) {padding-top: calc(2 * var(--gap));} -.t18.t18[data-size="large"][data-selected] {padding-top: calc(3 * var(--gap));} -.t18.t18[data-size="medium"]:not([data-selected]) {padding-top: calc(2 * var(--gap));} -.t18.t18[data-selected][data-size="medium"] {padding-top: calc(2 * var(--gap));}" +".t17.t17 {display: block;} +.t17.t17:not([data-size="large"]):not([data-selected]):not([data-size="medium"]) {padding-top: var(--gap);} +.t17.t17[data-size="large"]:not([data-selected]) {padding-top: var(--gap);} +.t17.t17[data-selected]:not([data-size="large"]):not([data-size="medium"]) {padding-top: calc(2 * var(--gap));} +.t17.t17[data-size="large"][data-selected] {padding-top: calc(3 * var(--gap));} +.t17.t17[data-size="medium"]:not([data-selected]) {padding-top: calc(2 * var(--gap));} +.t17.t17[data-selected][data-size="medium"] {padding-top: calc(2 * var(--gap));}" `; exports[`tasty() API should pass styles from tasty 1`] = `".t2.t2 {display: block; color: rgb(var(--clear-color-rgb) / .1); --current-color: var(--clear-color, clear); --current-color-rgb: var(--clear-color-rgb);}"`; -exports[`tasty() API should preserve null values in state-map-of-arrays conversion 1`] = ` -".t21.t21 {display: block;} -@media (min-width: 768px) {.t21.t21:not([data-disabled]):not([data-hovered]) {padding-top: calc(4 * var(--gap)); padding-right: calc(4 * var(--gap)); padding-bottom: calc(4 * var(--gap)); padding-left: calc(4 * var(--gap));}} -@media (min-width: 768px) {.t21.t21[data-disabled]:not([data-hovered]) {padding-top: var(--gap); padding-right: var(--gap); padding-bottom: var(--gap); padding-left: var(--gap);}} -@media (min-width: 768px) {.t21.t21[data-disabled][data-hovered] {padding-top: var(--gap); padding-right: var(--gap); padding-bottom: var(--gap); padding-left: var(--gap);}} -@media (max-width: 767px) {.t21.t21:not([data-disabled]):not([data-hovered]) {padding-top: calc(2 * var(--gap)); padding-right: calc(2 * var(--gap)); padding-bottom: calc(2 * var(--gap)); padding-left: calc(2 * var(--gap));}} -@media (max-width: 767px) {.t21.t21[data-disabled]:not([data-hovered]) {padding-top: var(--gap); padding-right: var(--gap); padding-bottom: var(--gap); padding-left: var(--gap);}} -@media (max-width: 767px) {.t21.t21[data-hovered]:not([data-disabled]) {padding-top: calc(3 * var(--gap)); padding-right: calc(3 * var(--gap)); padding-bottom: calc(3 * var(--gap)); padding-left: calc(3 * var(--gap));}} -@media (max-width: 767px) {.t21.t21[data-disabled][data-hovered] {padding-top: var(--gap); padding-right: var(--gap); padding-bottom: var(--gap); padding-left: var(--gap);}} -.t21.t21:not([data-disabled]):not([data-hovered]) {background-color: var(--white-color);} -.t21.t21:not([data-disabled]):not([data-hovered])>* {--context-fill-color: var(--white-color); --context-fill-color-rgb: var(--white-color-rgb);} -.t21.t21[data-disabled]:not([data-hovered]) {background-color: var(--gray-color);} -.t21.t21[data-disabled]:not([data-hovered])>* {--context-fill-color: var(--gray-color); --context-fill-color-rgb: var(--gray-color-rgb);} -.t21.t21[data-hovered]:not([data-disabled]) {background-color: var(--blue-color);} -.t21.t21[data-hovered]:not([data-disabled])>* {--context-fill-color: var(--blue-color); --context-fill-color-rgb: var(--blue-color-rgb);} -.t21.t21[data-disabled][data-hovered] {background-color: var(--gray-color);} -.t21.t21[data-disabled][data-hovered]>* {--context-fill-color: var(--gray-color); --context-fill-color-rgb: var(--gray-color-rgb);}" -`; - -exports[`tasty() API should preserve null values in state-map-of-arrays conversion 2`] = ` -".t21.t21 {display: block;} -@media (min-width: 768px) {.t21.t21:not([data-disabled]):not([data-hovered]) {padding-top: calc(4 * var(--gap)); padding-right: calc(4 * var(--gap)); padding-bottom: calc(4 * var(--gap)); padding-left: calc(4 * var(--gap));}} -@media (min-width: 768px) {.t21.t21[data-disabled]:not([data-hovered]) {padding-top: var(--gap); padding-right: var(--gap); padding-bottom: var(--gap); padding-left: var(--gap);}} -@media (min-width: 768px) {.t21.t21[data-disabled][data-hovered] {padding-top: var(--gap); padding-right: var(--gap); padding-bottom: var(--gap); padding-left: var(--gap);}} -@media (max-width: 767px) {.t21.t21:not([data-disabled]):not([data-hovered]) {padding-top: calc(2 * var(--gap)); padding-right: calc(2 * var(--gap)); padding-bottom: calc(2 * var(--gap)); padding-left: calc(2 * var(--gap));}} -@media (max-width: 767px) {.t21.t21[data-disabled]:not([data-hovered]) {padding-top: var(--gap); padding-right: var(--gap); padding-bottom: var(--gap); padding-left: var(--gap);}} -@media (max-width: 767px) {.t21.t21[data-hovered]:not([data-disabled]) {padding-top: calc(3 * var(--gap)); padding-right: calc(3 * var(--gap)); padding-bottom: calc(3 * var(--gap)); padding-left: calc(3 * var(--gap));}} -@media (max-width: 767px) {.t21.t21[data-disabled][data-hovered] {padding-top: var(--gap); padding-right: var(--gap); padding-bottom: var(--gap); padding-left: var(--gap);}} -.t21.t21:not([data-disabled]):not([data-hovered]) {background-color: var(--white-color);} -.t21.t21:not([data-disabled]):not([data-hovered])>* {--context-fill-color: var(--white-color); --context-fill-color-rgb: var(--white-color-rgb);} -.t21.t21[data-disabled]:not([data-hovered]) {background-color: var(--gray-color);} -.t21.t21[data-disabled]:not([data-hovered])>* {--context-fill-color: var(--gray-color); --context-fill-color-rgb: var(--gray-color-rgb);} -.t21.t21[data-hovered]:not([data-disabled]) {background-color: var(--blue-color);} -.t21.t21[data-hovered]:not([data-disabled])>* {--context-fill-color: var(--blue-color); --context-fill-color-rgb: var(--blue-color-rgb);} -.t21.t21[data-disabled][data-hovered] {background-color: var(--gray-color);} -.t21.t21[data-disabled][data-hovered]>* {--context-fill-color: var(--gray-color); --context-fill-color-rgb: var(--gray-color-rgb);}" -`; - exports[`tasty() API should support camelCase modifiers 1`] = ` ".t5.t5 {display: block;} .t5.t5:not([data-somehow-modified]) {color: var(--dark-color); --current-color: var(--dark-color, dark); --current-color-rgb: var(--dark-color-rgb);} diff --git a/src/tasty/index.ts b/src/tasty/index.ts index 96ff2c68e..15a86d130 100644 --- a/src/tasty/index.ts +++ b/src/tasty/index.ts @@ -3,21 +3,15 @@ export * from './utils/filterBaseProps'; export * from './utils/colors'; export * from './utils/styles'; export * from './utils/modAttrs'; -export * from './utils/responsive'; export * from './utils/renderStyles'; export * from './utils/dotize'; export * from './styles/list'; -export * from './providers/BreakpointsProvider'; export * from './utils/mergeStyles'; export * from './utils/warnings'; export * from './utils/getDisplayName'; export * from './injector'; export * from './debug'; -export type { - TastyProps, - GlobalTastyProps, - AllBasePropsWithMods, -} from './tasty'; +export type { TastyProps, AllBasePropsWithMods } from './tasty'; export type { AllBaseProps, BaseProps, diff --git a/src/tasty/providers/BreakpointsProvider.tsx b/src/tasty/providers/BreakpointsProvider.tsx deleted file mode 100644 index bbe061bfb..000000000 --- a/src/tasty/providers/BreakpointsProvider.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { createContext, ReactNode } from 'react'; - -// Default breakpoints mirror Bootstrap defaults without md and xxl breakpoints. -export const BreakpointsContext = createContext([980]); - -interface BreakpointsProviderProps { - value: number[]; - children: ReactNode; -} - -export function BreakpointsProvider({ - value, - children, -}: BreakpointsProviderProps) { - return ( - - {children} - - ); -} diff --git a/src/tasty/styles/types.ts b/src/tasty/styles/types.ts index a0203d735..08826cc3a 100644 --- a/src/tasty/styles/types.ts +++ b/src/tasty/styles/types.ts @@ -1,6 +1,6 @@ import { CSSProperties } from 'react'; -import { ResponsiveStyleValue } from '../utils/styles'; +import { StyleValue, StyleValueStateMap } from '../utils/styles'; type NamedColor = | 'purple' @@ -479,11 +479,14 @@ export type Selector = `${SuffixForSelector}${string}`; export type NotSelector = Exclude; export type StylesWithoutSelectors = { - [key in keyof StylesInterface]?: ResponsiveStyleValue; + [key in keyof StylesInterface]?: + | StyleValue + | StyleValueStateMap; }; export type Styles = StylesWithoutSelectors & { [key: string]: - | ResponsiveStyleValue + | StyleValue + | StyleValueStateMap | Styles; /** * Selector combinator: `undefined` (descendant, default), `'>'` (child), `'+'` (adjacent), `'~'` (sibling). diff --git a/src/tasty/tasty.test.tsx b/src/tasty/tasty.test.tsx index a35eedbe2..e16ad9003 100644 --- a/src/tasty/tasty.test.tsx +++ b/src/tasty/tasty.test.tsx @@ -6,7 +6,6 @@ import { Block } from '../components/Block'; import { Space } from '../components/layout/Space'; import { tastyDebug } from './debug'; -import { BreakpointsProvider } from './providers/BreakpointsProvider'; import { CONTAINER_STYLES } from './styles/list'; import { tasty } from './tasty'; @@ -147,13 +146,6 @@ describe('tasty() API', () => { expect(getByTestId(container, 'Field', {})).toBeDefined(); }); - it('should create responsive styles', () => { - const StyledBlock = tasty(Block, { styles: { display: ['grid', 'flex'] } }); - const { container } = render(); - - expect(container).toMatchTastySnapshot(); - }); - it('should create element styles', () => { const Block = tasty({ styles: { Element: { color: { '': '#dark', modified: '#purple' } } }, @@ -270,320 +262,6 @@ describe('tasty() API', () => { expect(container3).toMatchTastySnapshot(); }); - - it('should handle arrays containing state maps', () => { - // Test the new syntax: padding: ['1x', { '': '1x', large: '2x' }] - const StyledBlock = tasty(Block, { - styles: { - // Simple array with state map at specific breakpoint - padding: ['2x', { '': '1x', hovered: '3x' }], - - // Array with multiple state maps - margin: [ - '1x', - { '': '2x', pressed: '1x', disabled: '0' }, - { '': '0.5x', focused: '1x' }, - ], - - // Mixed responsive and state syntax - fill: { - '': ['#white', '#gray.05'], - hovered: ['#blue.05', '#blue.10'], - }, - }, - }); - - const { container } = render( - - - , - ); - - expect(container).toMatchTastySnapshot(); - }); - - it('should handle state-map-of-arrays pattern', () => { - // Test conversion from state-map-of-arrays to arrays-of-state-maps - const StyledBlock = tasty(Block, { - styles: { - // State map where values are responsive arrays - padding: { - '': ['4x', '2x', '1x'], - hovered: ['6x', '3x', '1.5x'], - 'variant=compact': ['2x', '1x', '0.5x'], - }, - - // Border with responsive arrays in state map - border: { - '': ['2bw solid #border', '1bw solid #border', 'none'], - focused: [ - '3bw solid #primary', - '2bw solid #primary', - '1bw solid #primary', - ], - 'error & focused': [ - '3bw solid #danger', - '2bw solid #danger', - '1bw solid #danger', - ], - }, - }, - }); - - const { container } = render( - - - , - ); - - expect(container).toMatchTastySnapshot(); - }); - - it('should preserve null values in state-map-of-arrays conversion', () => { - // Test that null values in arrays are preserved across all breakpoints - // This is important for state logic - missing state !== falsy state - const StyledBlock = tasty(Block, { - styles: { - // Test case: { '': ['1x', '2x'], large: [null, '3x'] } - // Should convert to: [ { '': '1x', large: null }, { '': '2x', large: '3x' } ] - padding: { - '': ['4x', '2x'], // All breakpoints get values - hovered: [null, '3x'], // First breakpoint gets null, second gets '3x' - disabled: ['1x', null], // First breakpoint gets '1x', second gets null - }, - - // Color to visualize the states are working - fill: { - '': '#white', - hovered: '#blue', - disabled: '#gray', - }, - }, - }); - - // Test with hovered=true (should use null for first breakpoint, '3x' for second) - const { container: hoveredContainer } = render( - - - , - ); - - expect(hoveredContainer).toMatchTastySnapshot(); - - // Test with disabled=true (should use '1x' for first breakpoint, null for second) - const { container: disabledContainer } = render( - - - , - ); - - expect(disabledContainer).toMatchTastySnapshot(); - }); - - it('should handle complex responsive styles with state binding', () => { - const ComplexCard = tasty(Block, { - styles: { - // Responsive layout that changes between flex and grid - display: ['grid', 'flex', 'block'], - - // Responsive gap with different values per breakpoint - gap: ['3x', '2x', '1x'], - - // Complex responsive padding with state modifiers - padding: { - '': ['4x', '3x', '2x'], - hovered: ['5x', '4x', '3x'], - 'pressed & !disabled': ['3x', '2x', '1x'], - 'variant=compact': ['2x', '1x', '0.5x'], - }, - - // Responsive width with complex logic - width: { - '': ['max 1200px', 'max 800px', 'max 100%'], - 'expanded | size=large': ['max 1400px', 'max 1000px', 'max 100%'], - '(hovered | focused) & !disabled': [ - 'max 1300px', - 'max 900px', - 'max 100%', - ], - }, - - // Color changes based on state with fallback - fill: { - '': '#surface', - hovered: '#surface-hover', - pressed: '#surface-pressed', - disabled: '#surface-disabled', - 'variant=danger & hovered': '#danger-hover', - 'variant=success & !disabled': '#success', - }, - - // Responsive border with state combinations - border: { - '': ['2bw solid #border', '1bw solid #border', 'none'], - focused: [ - '3bw solid #primary', - '2bw solid #primary', - '1bw solid #primary', - ], - 'error & focused': [ - '3bw solid #danger', - '2bw solid #danger', - '1bw solid #danger', - ], - '!variant=borderless & hovered': [ - '2bw solid #border-hover', - '1bw solid #border-hover', - '1bw solid #border-hover', - ], - }, - - // Responsive radius - radius: ['2r', '1r', '0.5r'], - - // Sub-element styling with responsive behavior - Header: { - preset: ['h2', 'h3', 'h4'], - color: { - '': '#text-primary', - 'variant=danger': '#danger', - hovered: '#text-primary-hover', - }, - margin: ['0 0 2x 0', '0 0 1x 0', '0 0 0.5x 0'], - }, - - Content: { - padding: ['2x', '1x', '0.5x'], - color: { - '': '#text', - disabled: '#text-disabled', - 'highlighted & !disabled': '#text-highlighted', - }, - }, - - Footer: { - display: { - '': ['flex', 'flex', 'none'], - expanded: ['flex', 'flex', 'flex'], - }, - gap: ['2x', '1x', '0.5x'], - padding: { - '': ['2x top', '1x top', '0.5x top'], - compact: ['1x top', '0.5x top', '0'], - }, - }, - }, - }); - - // Test with various state combinations - wrap with custom breakpoints for 3-value arrays - const { container } = render( - - -
Complex Header
-
Dynamic content
-
Footer content
-
-
, - ); - - expect(container).toMatchTastySnapshot(); - }); - - it('should handle complex gridAreas with responsive arrays and state modifiers', () => { - const Header = tasty({ - as: 'header', - styles: { - position: { '': 'static', sticky: 'sticky' }, - top: { sticky: '0' }, - fill: { '': 'transparent', sticky: '#white' }, - zIndex: { '': 'auto', sticky: 10 }, - shadow: { '': 'none', sticky: '0 0.5x 0.5x #white' }, - display: 'grid', - padding: '1x 2x', - height: 'min 6x', - gridAreas: [ - { - '': ` - "breadcrumbs breadcrumbs breadcrumbs breadcrumbs breadcrumbs breadcrumbs" - "back title . subtitle spacer extra" - "back title . subtitle spacer extra" - "content content content content content content" - "footer footer footer footer footer footer"`, - - 'back-button-top': ` - "back back back back back back" - "breadcrumbs breadcrumbs breadcrumbs breadcrumbs breadcrumbs breadcrumbs" - ". title . subtitle spacer extra" - ". title . subtitle spacer extra" - "content content content content content content" - "footer footer footer footer footer footer"`, - }, - { - '': ` - "breadcrumbs breadcrumbs breadcrumbs breadcrumbs" - "back title spacer extra" - "back subtitle subtitle extra" - "back . . extra" - "content content content content" - "footer footer footer footer"`, - - 'back-button-top': ` - "back back back back" - "breadcrumbs breadcrumbs breadcrumbs breadcrumbs" - ". title spacer extra" - ". subtitle subtitle extra" - ". . . extra" - "content content content content" - "footer footer footer footer"`, - }, - ], - gridColumns: [ - 'max-content minmax(2x, auto) 2x minmax(0, auto) minmax(2x, 1fr) minmax(min-content, max-content)', - 'max-content minmax(2x, auto) minmax(2x, 1fr) minmax(min-content, max-content)', - ], - placeItems: 'center stretch', - placeContent: 'stretch', - }, - }); - - // Test with default state - const { container: defaultContainer } = render( - -
- , - ); - - // Demonstrate debug utilities usage - const headerElement = defaultContainer.querySelector( - '[data-qa="default-grid"]', - ) as Element; - - // Example: Get CSS for specific element - const cssForElement = tastyDebug.css(headerElement); - expect(cssForElement).toContain('grid-template-areas'); - - // Example: Get CSS for specific class - const className = headerElement.className - .split(' ') - .find((cls) => /^t\d+$/.test(cls)); - if (className) { - const cssForClass = tastyDebug.css(className); - expect(cssForClass).toContain('display: grid'); - } - - expect(defaultContainer).toMatchTastySnapshot(); - }); }); describe('style order consistency', () => { @@ -922,33 +600,6 @@ describe('tastyGlobal() API', () => { expect(styleContent).toContain('color: var(--white-color)'); }); - it('should support responsive global styles', () => { - const GlobalCard = tasty('.responsive-card', { - padding: ['4x', '2x', '1x'], - width: ['max 800px', 'max 600px', 'max 100%'], - margin: ['2x auto', '1x auto', '0 auto'], - }); - - const { container } = render( - -
- -
Responsive Card Content
-
-
, - ); - - // Verify responsive global styles are injected - const styleElements = document.head.querySelectorAll('[data-tasty]'); - const styleContent = Array.from(styleElements) - .map((el) => el.textContent) - .join(''); - - expect(styleContent).toContain('.responsive-card'); - expect(styleContent).toContain('@media'); - expect(styleContent).toContain('max-width: 800px'); - }); - it('should support state-based global styles', () => { const GlobalInteractive = tasty('.interactive-element', { fill: { @@ -987,30 +638,6 @@ describe('tastyGlobal() API', () => { expect(styleContent).toContain('background-color: var(--white-color)'); }); - it('should handle custom breakpoints prop', () => { - const GlobalResponsive = tasty('.custom-breakpoints', { - padding: ['3x', '2x', '1x'], - display: ['grid', 'flex', 'block'], - }); - - const { container } = render( -
- -
Custom Breakpoint Element
-
, - ); - - // Verify custom breakpoints are used in global styles - const styleElements = document.head.querySelectorAll('[data-tasty]'); - const styleContent = Array.from(styleElements) - .map((el) => el.textContent) - .join(''); - - expect(styleContent).toContain('.custom-breakpoints'); - expect(styleContent).toContain('@media (min-width: 1440px)'); - expect(styleContent).toContain('@media (min-width: 900px)'); - }); - it('should cleanup styles when component unmounts', () => { const GlobalTemporary = tasty('.temporary-element', { fill: '#red', @@ -1322,34 +949,6 @@ describe('tastyGlobal() API', () => { expect(styleContent).toContain('color: var(--link-color)'); }); - it('should handle breakpoints context changes', () => { - const GlobalResponsive = tasty('.context-responsive', { - padding: ['4x', '2x', '1x'], - width: ['max 1000px', 'max 600px', 'max 100%'], - }); - - // Test with breakpoint context - render( - -
- -
- Context with custom breakpoints -
-
-
, - ); - - // Verify styles with breakpoint context are injected - const styleElements = document.head.querySelectorAll('[data-tasty]'); - const styleContent = Array.from(styleElements) - .map((el) => el.textContent) - .join(''); - expect(styleContent).toContain('.context-responsive'); - expect(styleContent).toContain('@media (min-width: 1200px)'); - expect(styleContent).toContain('@media (min-width: 768px)'); - }); - it('should have correct displayName', () => { const GlobalTest = tasty('.test-selector', { color: '#red', @@ -1477,48 +1076,6 @@ describe('tastyGlobal() API', () => { expect(styleContent).toContain('color: var(--blue-color)'); }); - it('should handle style updates when breakpoints change', () => { - const GlobalDynamic = tasty('.dynamic-styles', { - padding: ['3x', '2x', '1x'], - display: ['grid', 'flex', 'block'], - }); - - const TestWrapper = ({ breakpoints }: { breakpoints: number[] }) => ( - -
- -
Dynamic element
-
-
- ); - - const { container, rerender } = render( - , - ); - - // Verify initial breakpoint styles - let styleElements = document.head.querySelectorAll('[data-tasty]'); - let styleContent = Array.from(styleElements) - .map((el) => el.textContent) - .join(''); - expect(styleContent).toContain('.dynamic-styles'); - expect(styleContent).toContain('@media (min-width: 1200px)'); - expect(styleContent).toContain('@media (min-width: 768px)'); - - // Change breakpoints - should trigger style re-calculation - act(() => { - rerender(); - }); - - // Verify updated breakpoint styles - styleElements = document.head.querySelectorAll('[data-tasty]'); - styleContent = Array.from(styleElements) - .map((el) => el.textContent) - .join(''); - expect(styleContent).toContain('@media (min-width: 1440px)'); - expect(styleContent).toContain('@media (min-width: 900px)'); - }); - it('should handle style updates when styles change', () => { const DynamicGlobal1 = tasty('.dynamic-selector', { fill: '#blue', diff --git a/src/tasty/tasty.tsx b/src/tasty/tasty.tsx index 5800cf333..35490284b 100644 --- a/src/tasty/tasty.tsx +++ b/src/tasty/tasty.tsx @@ -14,7 +14,6 @@ import { import { isValidElementType } from 'react-is'; import { allocateClassName, inject, injectGlobal } from './injector'; -import { BreakpointsContext } from './providers/BreakpointsProvider'; import { BASE_STYLES } from './styles/list'; import { Styles, StylesInterface } from './styles/types'; import { AllBaseProps, BaseProps, BaseStyleProps, Props } from './types'; @@ -23,7 +22,11 @@ import { getDisplayName } from './utils/getDisplayName'; import { mergeStyles } from './utils/mergeStyles'; import { modAttrs } from './utils/modAttrs'; import { RenderResult, renderStyles } from './utils/renderStyles'; -import { ResponsiveStyleValue, stringifyStyles } from './utils/styles'; +import { + stringifyStyles, + StyleValue, + StyleValueStateMap, +} from './utils/styles'; /** * Mapping of is* properties to their corresponding HTML attributes @@ -101,12 +104,10 @@ export type TastyProps< Pick & WithVariant; -export interface GlobalTastyProps { - breakpoints?: number[]; -} - export type AllBasePropsWithMods = AllBaseProps & { - [key in K[number]]?: ResponsiveStyleValue; + [key in K[number]]?: + | StyleValue + | StyleValueStateMap; } & BaseStyleProps; type TastyComponentPropsWithDefaults< @@ -152,18 +153,13 @@ export function tasty< // Internal specialized implementations function tastyGlobal(selector: string, styles?: Styles) { - const _StyleDeclarationComponent: FC = ({ - breakpoints, - }) => { - let contextBreakpoints = useContext(BreakpointsContext); - - const breakpointsList = (breakpoints ?? contextBreakpoints) || [980]; + const _StyleDeclarationComponent: FC = () => { const disposeRef = useRef<(() => void) | null>(null); const styleResults = useMemo(() => { if (!styles) return []; - return renderStyles(styles, breakpointsList, selector); - }, [selector, styles, breakpointsList]); + return renderStyles(styles, selector); + }, [selector, styles]); // Inject styles at insertion phase; cleanup on change/unmount useInsertionEffect(() => { @@ -315,9 +311,9 @@ function tastyElement( * An additional optimization that allows to avoid rendering styles across various instances * of the same element if no custom styles are provided via `styles` prop or direct style props. */ - const renderDefaultStyles = cacheWrapper((breakpoints: number[]) => { + const renderDefaultStyles = cacheWrapper(() => { // Return rules without className - injector will add it - return renderStyles(defaultStyles || {}, breakpoints); + return renderStyles(defaultStyles || {}); }); let { @@ -335,7 +331,6 @@ function tastyElement( as, styles, variant: _omitVariant, - breakpoints, mods, element, qa, @@ -369,15 +364,6 @@ function tastyElement( styles = undefined as unknown as Styles; } - let contextBreakpoints = useContext(BreakpointsContext); - breakpoints = (breakpoints as number[] | undefined) ?? contextBreakpoints; - - // Memoize breakpoints key once - const breakpointsKey = useMemo( - () => (breakpoints as number[] | undefined)?.join(',') || '', - [breakpoints?.join(',')], - ); - const propStylesKey = stringifyStyles(propStyles); // Optimize style computation and cache key generation @@ -393,29 +379,26 @@ function tastyElement( // Generate cache key for style deduplication const styleKey = stringifyStyles(merged || {}); - const key = generateStyleCacheKey( - styleKey, - breakpointsKey ? `bp:${breakpointsKey}` : undefined, - ); + const key = generateStyleCacheKey(styleKey); return { allStyles: merged, cacheKey: key, useDefaultStyles: useDefault, }; - }, [styles, propStylesKey, breakpointsKey]); + }, [styles, propStylesKey]); // Compute rules synchronously; inject via insertion effect const directResult: RenderResult = useMemo(() => { if (useDefaultStyles) { - return renderDefaultStyles(breakpoints as number[]); + return renderDefaultStyles(); } else if (allStyles && Object.keys(allStyles).length > 0) { // Return rules without className - injector will add it - return renderStyles(allStyles, breakpoints as number[]); + return renderStyles(allStyles); } else { return { rules: [], className: '' }; } - }, [useDefaultStyles, allStyles, breakpointsKey, cacheKey]); + }, [useDefaultStyles, allStyles, cacheKey]); const disposeRef = useRef<(() => void) | null>(null); diff --git a/src/tasty/utils/renderStyles.ts b/src/tasty/utils/renderStyles.ts index 94c79c0c5..7a728117a 100644 --- a/src/tasty/utils/renderStyles.ts +++ b/src/tasty/utils/renderStyles.ts @@ -16,11 +16,6 @@ import { createStyle, STYLE_HANDLER_MAP } from '../styles'; import { Styles } from '../styles/types'; import { getModCombinationsIterative } from './getModCombinations'; -import { - normalizeStyleZones, - pointsToZones, - ResponsiveZone, -} from './responsive'; import { computeState, getModSelector, @@ -30,12 +25,6 @@ import { styleStateMapToStyleStateDataList, } from './styles'; -// Detect if a value is a state map whose entries contain responsive arrays -function stateMapHasResponsiveArrays(value: any): boolean { - if (!value || typeof value !== 'object' || Array.isArray(value)) return false; - return Object.values(value).some((v) => Array.isArray(v)); -} - export interface StyleResult { selector: string; declarations: string; @@ -50,17 +39,12 @@ export interface RenderResult { interface LogicalRule { selectorSuffix: string; // '', ':hover', '>*', … - breakpointIdx: number; // 0 = base declarations: Record; - // Marks that this rule originated from responsive array processing - // When true and breakpointIdx === 0, we should wrap the rule in the zone[0] media query - responsiveSource?: boolean; } type HandlerQueueItem = { handler: StyleHandler; styleMap: StyleMap; - isResponsive: boolean; }; // Cache logical rules per styles+breakpoints to avoid recomputation across identical calls @@ -529,17 +513,10 @@ function filterModsByPriority( /** * Explode a style handler result into logical rules with proper mapping - * Phase 1: Handler fan-out ($ selectors, arrays) - * Phase 2: Responsive fan-out (breakpoint arrays) - * Phase 3: Rule materialization + * Phase 1: Handler fan-out ($ selectors) + * Phase 2: Rule materialization */ -function explodeHandlerResult( - result: any, - zones: ResponsiveZone[], - selectorSuffix = '', - forceBreakpointIdx?: number, - responsiveOrigin: boolean = false, -): LogicalRule[] { +function explodeHandlerResult(result: any, selectorSuffix = ''): LogicalRule[] { if (!result) return []; // Phase 1: Handler fan-out - normalize to array @@ -551,63 +528,25 @@ function explodeHandlerResult( const { $, ...styleProps } = item; - // Phase 2: Responsive fan-out - handle array values - const breakpointGroups = new Map>(); - - if (forceBreakpointIdx !== undefined) { - // When breakpoint is forced (from responsive processing), use all props for that breakpoint - const group: Record = {}; - for (const [prop, value] of Object.entries(styleProps)) { - if (value != null && value !== '') { - group[prop] = String(value); - } - } - if (Object.keys(group).length > 0) { - breakpointGroups.set(forceBreakpointIdx, group); - } - } else { - // Normal processing - handle responsive arrays - const responsiveProps: Array<{ - prop: string; - value: any; - breakpointIdx: number; - }> = []; - - for (const [prop, value] of Object.entries(styleProps)) { - if (Array.isArray(value)) { - // Responsive array - create entry for each breakpoint - value.forEach((val, idx) => { - if (val != null && val !== '' && idx < zones.length) { - responsiveProps.push({ prop, value: val, breakpointIdx: idx }); - } - }); - } else if (value != null && value !== '') { - // Single value - goes to base breakpoint - responsiveProps.push({ prop, value, breakpointIdx: 0 }); - } - } - - // Group by breakpoint index - for (const { prop, value, breakpointIdx } of responsiveProps) { - const group = breakpointGroups.get(breakpointIdx) || {}; - group[prop] = String(value); - breakpointGroups.set(breakpointIdx, group); + // Build declarations from style props + const declarations: Record = {}; + for (const [prop, value] of Object.entries(styleProps)) { + if (value != null && value !== '') { + declarations[prop] = String(value); } } - // Phase 3: Selector fan-out - handle $ suffixes + if (Object.keys(declarations).length === 0) continue; + + // Phase 2: Selector fan-out - handle $ suffixes // IMPORTANT: If we are already in a pseudo-element context (contains '::'), // CSS does not allow further descendant/child selectors (e.g., '>*') after - // a pseudo-element. In such cases we must ignore only the `$`-derived - // selectors while still preserving base declarations for the current - // selector. Previously this branch returned early and accidentally dropped - // all declarations computed before, including valid base ones. + // a pseudo-element. In such cases we must ignore the `$`-derived selectors. const inPseudoElementContext = selectorSuffix.includes('::'); if (inPseudoElementContext && $) { // Skip this item entirely to avoid producing invalid selectors like - // `.t0::before>*`. Other items (without $) in the same handler result - // will still be processed and preserved. + // `.t0::before>*`. continue; } @@ -617,43 +556,12 @@ function explodeHandlerResult( ) : [selectorSuffix]; - // Early identical-breakpoint coalescing: skip duplicate declarations - const seenDeclarations = new Map(); - - // Process breakpoints in order to prefer lower breakpoint indices - const sortedBreakpoints = Array.from(breakpointGroups.entries()).sort( - ([a], [b]) => a - b, - ); - - for (const [breakpointIdx, declarations] of sortedBreakpoints) { - if (Object.keys(declarations).length === 0) continue; - - // Create a stable hash key for identical declarations - const declarationKeys = Object.keys(declarations).sort(); - const declarationHash = declarationKeys - .map((key) => `${key}:${declarations[key]}`) - .join(';'); - - const existingBreakpointIdx = seenDeclarations.get(declarationHash); - if (existingBreakpointIdx !== undefined) { - // Skip this breakpoint as it has identical declarations to a previous one - // The CSS cascade will handle the responsive behavior correctly - continue; - } - - // Mark this declaration set as seen - seenDeclarations.set(declarationHash, breakpointIdx); - - // Create logical rules for this unique declaration set - for (const suffix of suffixes) { - logicalRules.push({ - selectorSuffix: suffix, - breakpointIdx, - declarations, - responsiveSource: - responsiveOrigin || forceBreakpointIdx !== undefined, - }); - } + // Create logical rules for each suffix + for (const suffix of suffixes) { + logicalRules.push({ + selectorSuffix: suffix, + declarations: { ...declarations }, + }); } } @@ -732,13 +640,9 @@ function convertHandlerResultToCSS(result: any, selectorSuffix = ''): string { function processStateMapsWithModCombinations( styleStates: Record, lookupStyles: string[], - zones: ResponsiveZone[], handler: StyleHandler, parentSuffix: string, allLogicalRules: LogicalRule[], - cachedNormalizeStyleZones: (value: any, zoneNumber: number) => any, - breakpointIdx?: number, - responsiveOrigin: boolean = false, ): void { // Collect all mods from style states const allMods: string[] = []; @@ -772,13 +676,7 @@ function processStateMapsWithModCombinations( const result = handler(stateProps as any); if (!result) return; - const logicalRules = explodeHandlerResult( - result, - zones, - parentSuffix, - breakpointIdx, - responsiveOrigin, - ); + const logicalRules = explodeHandlerResult(result, parentSuffix); allLogicalRules.push(...logicalRules); return; } @@ -859,52 +757,14 @@ function processStateMapsWithModCombinations( }) .join('')}`; - // Check if any state value is responsive (array) - const hasResponsiveStateValues = lookupStyles.some((style) => - Array.isArray(stateProps[style]), + // Simple non-responsive state values + const result = handler(stateProps as any); + if (!result) return; + const logical = explodeHandlerResult( + result, + `${modsSelectors}${parentSuffix}`, ); - - if (hasResponsiveStateValues) { - // Fan out by breakpoint for responsive state values - const propsByPoint = zones.map((_, i) => { - const pointProps: Record = {}; - lookupStyles.forEach((style) => { - const v = stateProps[style]; - if (Array.isArray(v)) { - const arr = cachedNormalizeStyleZones(v, zones.length); - pointProps[style] = arr?.[i]; - } else { - pointProps[style] = v; - } - }); - return pointProps; - }); - - propsByPoint.forEach((props, bpIdx) => { - const res = handler(props as any); - if (!res) return; - const logical = explodeHandlerResult( - res, - zones, - `${modsSelectors}${parentSuffix}`, - bpIdx, - true, - ); - allLogicalRules.push(...logical); - }); - } else { - // Simple non-responsive state values - const result = handler(stateProps as any); - if (!result) return; - const logical = explodeHandlerResult( - result, - zones, - `${modsSelectors}${parentSuffix}`, - breakpointIdx, - responsiveOrigin, - ); - allLogicalRules.push(...logical); - } + allLogicalRules.push(...logical); }); } @@ -914,7 +774,6 @@ function processStateMapsWithModCombinations( function materializeRules( logicalRules: LogicalRule[], className: string, - zones: ResponsiveZone[], ): StyleResult[] { return logicalRules.map((rule) => { // Generate base selector @@ -929,18 +788,9 @@ function materializeRules( .map(([prop, value]) => `${prop}: ${value};`) .join(' '); - const q = - rule.breakpointIdx > 0 - ? zones[rule.breakpointIdx]?.mediaQuery - : rule.responsiveSource - ? zones[0]?.mediaQuery - : undefined; - const atRules = q ? [`@media ${q}`] : undefined; - return { selector, declarations, - atRules, }; }); } @@ -951,137 +801,10 @@ function materializeRules( */ function generateLogicalRules( styles: Styles, - responsive: number[] = [], parentSuffix: string = '', ): LogicalRule[] { - const zones = pointsToZones(responsive || []); const allLogicalRules: LogicalRule[] = []; - // Cache for normalizeStyleZones results to avoid repeated computation - // WeakMap allows automatic cleanup when arrays are garbage collected - const normalizeCache = new WeakMap>(); - - // Helper function to get cached normalizeStyleZones result - function cachedNormalizeStyleZones(value: any, zoneNumber: number): any { - // Only cache for arrays - other types are fast to process - if (!Array.isArray(value)) { - return normalizeStyleZones(value, zoneNumber); - } - - // Check if we have a cache for this array reference - let zoneCache = normalizeCache.get(value); - if (!zoneCache) { - zoneCache = new Map(); - normalizeCache.set(value, zoneCache); - } - - // Check if we have a cached result for this zone count - let result = zoneCache.get(zoneNumber); - if (result === undefined) { - result = normalizeStyleZones(value, zoneNumber); - zoneCache.set(zoneNumber, result); - } - - return result; - } - - // Local versions of helpers that leverage cachedNormalizeStyleZones - function stateMapToArrayOfStateMapsLocal( - value: Record, - zoneNumber: number, - ): Array> { - // Short-circuit for single zone - avoid array allocation - if (zoneNumber === 1) { - const singleMap: Record = {}; - for (const [state, stateValue] of Object.entries(value)) { - if (Array.isArray(stateValue)) { - // Take the first value from the array or null if empty - singleMap[state] = stateValue.length > 0 ? stateValue[0] : null; - } else { - singleMap[state] = stateValue; - } - } - return [singleMap]; - } - - const result: Array> = Array.from( - { length: zoneNumber }, - () => ({}), - ); - - for (const [state, stateValue] of Object.entries(value)) { - const perZone = Array.isArray(stateValue) - ? (cachedNormalizeStyleZones(stateValue, zoneNumber) as any[]) - : Array(zoneNumber).fill(stateValue); - - for (let i = 0; i < zoneNumber; i++) { - const v = perZone[i]; - result[i][state] = v; - } - } - - return result; - } - - function normalizeArrayWithStateMapsLocal( - valueArray: any[], - zoneNumber: number, - ): Array> { - // Short-circuit for single zone - avoid array propagation and mapping - if (zoneNumber === 1) { - const firstEntry = valueArray.length > 0 ? valueArray[0] : null; - if ( - firstEntry && - typeof firstEntry === 'object' && - !Array.isArray(firstEntry) - ) { - return [firstEntry as Record]; - } - return [{ '': firstEntry }]; - } - - const propagated = cachedNormalizeStyleZones( - valueArray as any, - zoneNumber, - ) as any[]; - - // Trim trailing null/undefined entries to reduce processing - let lastNonNullIndex = propagated.length - 1; - while (lastNonNullIndex >= 0 && propagated[lastNonNullIndex] == null) { - lastNonNullIndex--; - } - - // If all entries are null, return minimal array - if (lastNonNullIndex < 0) { - return Array.from({ length: zoneNumber }, () => ({ '': null })); - } - - // Process only up to the last non-null entry, then fill the rest with the last value - const result: Array> = []; - let lastProcessedEntry: Record | null = null; - - for (let i = 0; i <= lastNonNullIndex; i++) { - const entry = propagated[i]; - let processedEntry: Record; - - if (entry && typeof entry === 'object' && !Array.isArray(entry)) { - processedEntry = entry as Record; - } else { - processedEntry = { '': entry }; - } - - result.push(processedEntry); - lastProcessedEntry = processedEntry; - } - - // Fill remaining slots with the last processed entry (CSS cascade behavior) - for (let i = lastNonNullIndex + 1; i < zoneNumber; i++) { - result.push(lastProcessedEntry || { '': null }); - } - - return result; - } - // Process styles recursively, preserving mod selectors and combining with nested selector suffixes function processStyles(currentStyles: Styles, parentSuffix: string = '') { const keys = Object.keys(currentStyles || {}); @@ -1116,35 +839,11 @@ function generateLogicalRules( } seenHandlers.add(handler); - let isResponsive = false; const lookupStyles = handler.__lookupStyles; const filteredStyleMap = lookupStyles.reduce((map, name) => { const value = currentStyles?.[name]; if (value !== undefined) { - // Case 1: state-map-of-arrays → array-of-state-maps - if ( - value && - typeof value === 'object' && - !Array.isArray(value) && - stateMapHasResponsiveArrays(value) - ) { - (map as any)[name] = stateMapToArrayOfStateMapsLocal( - value as Record, - zones.length, - ); - isResponsive = true; - } else if (Array.isArray(value)) { - // Case 2: array that may contain state maps → normalize to array-of-state-maps - if (value.length > 0) { - (map as any)[name] = normalizeArrayWithStateMapsLocal( - value as any[], - zones.length, - ); - isResponsive = true; - } - } else { - (map as any)[name] = value; - } + (map as any)[name] = value; } return map; @@ -1153,121 +852,48 @@ function generateLogicalRules( handlerQueue.push({ handler, styleMap: filteredStyleMap, - isResponsive, }); }); }); - // Process handlers using the three-phase approach - handlerQueue.forEach(({ handler, styleMap, isResponsive }) => { + // Process handlers + handlerQueue.forEach(({ handler, styleMap }) => { const lookupStyles = handler.__lookupStyles; - if (isResponsive) { - // For responsive styles, resolve arrays using normalizeStyleZones - const valueMap = lookupStyles.reduce((map, style) => { - map[style] = cachedNormalizeStyleZones(styleMap[style], zones.length); - return map; - }, {} as any); - - // Create props for each breakpoint - const propsByPoint = zones.map((zone, i) => { - const pointProps = {} as any; - lookupStyles.forEach((style) => { - if (valueMap != null && valueMap[style] != null) { - pointProps[style] = valueMap[style][i]; - } - }); - return pointProps; - }); + // Check if any values have state maps + const hasStateMaps = lookupStyles.some((style) => { + const value = styleMap[style]; + return value && typeof value === 'object' && !Array.isArray(value); + }); - // Call handler for each breakpoint, with state map processing if needed - propsByPoint.forEach((pointProps, breakpointIdx) => { - const hasStateMapsAtPoint = lookupStyles.some((style) => { - const v = pointProps[style]; - return v && typeof v === 'object' && !Array.isArray(v); - }); - - if (hasStateMapsAtPoint) { - // Build styleStates from point props - const styleStates: Record = {}; - lookupStyles.forEach((style) => { - const v = pointProps[style]; - if (v && typeof v === 'object' && !Array.isArray(v)) { - const { states } = styleStateMapToStyleStateDataList(v); - styleStates[style] = states; - } else { - styleStates[style] = [{ mods: [], notMods: [], value: v }]; - } - }); - - // Use the consolidated helper for mod combination processing - processStateMapsWithModCombinations( - styleStates, - lookupStyles, - zones || [], - handler, - parentSuffix, - allLogicalRules, - cachedNormalizeStyleZones, - breakpointIdx, - true, - ); + if (hasStateMaps) { + // Build styleStates from styleMap + const styleStates: Record = {}; + lookupStyles.forEach((style) => { + const value = styleMap[style]; + if (value && typeof value === 'object' && !Array.isArray(value)) { + const { states } = styleStateMapToStyleStateDataList(value); + styleStates[style] = states; } else { - const result = handler(pointProps as any); - if (!result) return; - - const logicalRules = explodeHandlerResult( - result, - zones || [], - parentSuffix, - breakpointIdx, - true, - ); - allLogicalRules.push(...logicalRules); + // Simple value, create a single state + styleStates[style] = [{ mods: [], notMods: [], value }]; } }); - } else { - // For non-responsive styles, check if any values have state maps - const hasStateMaps = lookupStyles.some((style) => { - const value = styleMap[style]; - return value && typeof value === 'object' && !Array.isArray(value); - }); - if (hasStateMaps) { - // Build styleStates from styleMap - const styleStates: Record = {}; - lookupStyles.forEach((style) => { - const value = styleMap[style]; - if (value && typeof value === 'object' && !Array.isArray(value)) { - const { states } = styleStateMapToStyleStateDataList(value); - styleStates[style] = states; - } else { - // Simple value, create a single state - styleStates[style] = [{ mods: [], notMods: [], value }]; - } - }); - - // Use the consolidated helper for mod combination processing - processStateMapsWithModCombinations( - styleStates, - lookupStyles, - zones || [], - handler, - parentSuffix, - allLogicalRules, - cachedNormalizeStyleZones, - ); - } else { - // Simple case: no state maps, call handler directly - const result = handler(styleMap as any); - if (result) { - const logical = explodeHandlerResult( - result, - zones || [], - parentSuffix, - ); - allLogicalRules.push(...logical); - } + // Use the consolidated helper for mod combination processing + processStateMapsWithModCombinations( + styleStates, + lookupStyles, + handler, + parentSuffix, + allLogicalRules, + ); + } else { + // Simple case: no state maps, call handler directly + const result = handler(styleMap as any); + if (result) { + const logical = explodeHandlerResult(result, parentSuffix); + allLogicalRules.push(...logical); } } }); @@ -1283,19 +909,12 @@ function generateLogicalRules( * Render styles to StyleResult[] format (recommended) * Supports both component and global styling with advanced optimizations */ -export function renderStyles( - styles?: Styles, - responsive?: number[], - className?: string, -): RenderResult; +export function renderStyles(styles?: Styles, className?: string): RenderResult; /** * Render styles without className for element styles (injector will add it) */ -export function renderStyles( - styles: Styles | undefined, - responsive?: number[], -): RenderResult; +export function renderStyles(styles: Styles | undefined): RenderResult; /** * Render styles for direct injection with a specific selector @@ -1303,13 +922,11 @@ export function renderStyles( */ export function renderStyles( styles: Styles | undefined, - responsive: number[], selector: string, ): StyleResult[]; export function renderStyles( styles?: Styles, - responsive: number[] = [], classNameOrSelector?: string, ): RenderResult | StyleResult[] { const directSelector = !!classNameOrSelector; @@ -1318,16 +935,13 @@ export function renderStyles( return directSelector ? [] : { rules: [] }; } - // Generate logical rules using shared pipeline (memoized per styles+breakpoints) + // Generate logical rules using shared pipeline (memoized per styles) const stylesKey = stringifyStyles(styles); - const bpKey = (responsive || []).join(','); - const lrKey = `${stylesKey}#${bpKey}`; - let allLogicalRules = logicalRulesCache.get(lrKey); + let allLogicalRules = logicalRulesCache.get(stylesKey); if (!allLogicalRules) { - allLogicalRules = generateLogicalRules(styles, responsive); - logicalRulesCache.set(lrKey, allLogicalRules); + allLogicalRules = generateLogicalRules(styles); + logicalRulesCache.set(stylesKey, allLogicalRules); } - const zones = pointsToZones(responsive || []); if (directSelector) { // Direct selector mode: convert logical rules directly to StyleResult format @@ -1354,18 +968,9 @@ export function renderStyles( .map(([prop, value]) => `${prop}: ${value};`) .join(' '); - const q = - rule.breakpointIdx > 0 - ? zones[rule.breakpointIdx]?.mediaQuery - : rule.responsiveSource - ? zones[0]?.mediaQuery - : undefined; - const atRules = q ? [`@media ${q}`] : undefined; - return { selector: finalSelector, declarations, - atRules, }; }); } @@ -1374,8 +979,8 @@ export function renderStyles( const accumulatedRules = new Map(); for (const rule of allLogicalRules) { - // Create a key based on breakpointIdx, selectorSuffix, and responsiveOrigin - const ruleKey = `${rule.breakpointIdx}|${rule.selectorSuffix}|${rule.responsiveSource}`; + // Create a key based on selectorSuffix + const ruleKey = rule.selectorSuffix; const existing = accumulatedRules.get(ruleKey); if (existing) { @@ -1385,9 +990,7 @@ export function renderStyles( // Create a new accumulated rule accumulatedRules.set(ruleKey, { selectorSuffix: rule.selectorSuffix, - breakpointIdx: rule.breakpointIdx, declarations: { ...rule.declarations }, - responsiveSource: rule.responsiveSource, }); } } @@ -1400,18 +1003,9 @@ export function renderStyles( .map(([prop, value]) => `${prop}: ${value};`) .join(' '); - const q = - rule.breakpointIdx > 0 - ? zones[rule.breakpointIdx]?.mediaQuery - : rule.responsiveSource - ? zones[0]?.mediaQuery - : undefined; - const atRules = q ? [`@media ${q}`] : undefined; - return { selector: rule.selectorSuffix || '', declarations, - atRules, needsClassName: true, // Flag for injector to prepend className }; }, @@ -1426,7 +1020,6 @@ export function renderStyles( const finalRulesRaw = materializeRules( Array.from(accumulatedRules.values()), classNameOrSelector, - zones || [], ); // Simplified deduplication (should be much less work now) diff --git a/src/tasty/utils/responsive.ts b/src/tasty/utils/responsive.ts deleted file mode 100644 index 15b0b5ba0..000000000 --- a/src/tasty/utils/responsive.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { ResponsiveStyleValue } from './styles'; - -export interface ResponsiveZone { - max?: number; - min?: number; - mediaQuery?: string; -} - -const zonesCache = {}; - -export function pointsToZones(points: number[]) { - const cacheKey = points.join('|'); - - if (!zonesCache[cacheKey]) { - const zones: ResponsiveZone[] = []; - - points.forEach((point, i) => { - const zone: ResponsiveZone = {}; - - if (i) { - zone.max = points[i - 1] - 1; - } - - zone.min = point; - - zones.push(zone); - }); - - zones.push({ - max: points[points.length - 1] - 1, - }); - - zones.forEach((zone) => { - const queries: string[] = []; - - if (zone.min) { - queries.push(`(min-width: ${zone.min}px)`); - } - - if (zone.max) { - queries.push(`(max-width: ${zone.max}px)`); - } - - zone.mediaQuery = queries.join(' and '); - }); - - zonesCache[cacheKey] = zones; - } - - return zonesCache[cacheKey]; -} - -// export function getResponsiveValue(values, zoneNumber) { -// for (let i = zoneNumber; i >= 0; i--) { -// if (values[i] != null) -// } -// } - -export function normalizeStyleZones( - value: ResponsiveStyleValue, - zoneNumber: number, -) { - if (value == null) return value; - - const arr = Array.from(Array(zoneNumber)); - - if (typeof value === 'string') return arr.map(() => value); - - if (Array.isArray(value)) { - let prevValue = null; - - for (let i = 0; i < arr.length; i++) { - arr[i] = value[i] == null ? prevValue : value[i]; - - prevValue = arr[i]; - } - - return arr; - } - - return []; -} diff --git a/src/tasty/utils/styles.ts b/src/tasty/utils/styles.ts index b81e5bf96..631c4f54f 100644 --- a/src/tasty/utils/styles.ts +++ b/src/tasty/utils/styles.ts @@ -12,11 +12,11 @@ export type StyleValueStateMap = { [key: string]: StyleValue; }; -export type ResponsiveStyleValue = - | StyleValue - | StyleValue[] - | StyleValueStateMap - | StyleValueStateMap[]; +/** + * Combined type for style values that can be either a direct value or a state map. + * Use this for component props that accept style values. + */ +export type StylePropValue = StyleValue | StyleValueStateMap; export type ComputeModel = string | number; @@ -38,7 +38,7 @@ export type StyleHandler = RawStyleHandler & { export interface StyleStateData { model?: ComputeModel; tokens?: string[]; - value: ResponsiveStyleValue; + value: StyleValue | StyleValueStateMap; /** The list of mods to apply */ mods: string[]; /** The list of **not** mods to apply (e.g. `:not(:hover)`) */ @@ -55,7 +55,7 @@ export type StyleStateDataList = StyleStateData[]; export type StyleStateDataListMap = { [key: string]: StyleStateDataList }; -export type StyleMap = { [key: string]: ResponsiveStyleValue }; +export type StyleMap = { [key: string]: StyleValue | StyleValueStateMap }; export type StyleStateMap = { [key: string]: StyleStateData }; @@ -512,7 +512,7 @@ export const parseStateNotation = cacheWrapper(parseStateNotationInner); * Parse state notation and return tokens, modifiers and compute model. */ export function styleStateMapToStyleStateDataList( - styleStateMap: StyleStateMap | ResponsiveStyleValue, + styleStateMap: StyleStateMap | StyleValue | StyleValueStateMap, ): { states: StyleStateDataList; mods: string[] } { if (typeof styleStateMap !== 'object' || !styleStateMap) { return {