styles.rs

   1use proc_macro::TokenStream;
   2use proc_macro2::TokenStream as TokenStream2;
   3use quote::{format_ident, quote};
   4use syn::{
   5    braced,
   6    parse::{Parse, ParseStream, Result},
   7    parse_macro_input, Token, Visibility,
   8};
   9
  10#[derive(Debug)]
  11struct StyleableMacroInput {
  12    method_visibility: Visibility,
  13}
  14
  15impl Parse for StyleableMacroInput {
  16    fn parse(input: ParseStream) -> Result<Self> {
  17        if !input.peek(syn::token::Brace) {
  18            return Ok(Self {
  19                method_visibility: Visibility::Inherited,
  20            });
  21        }
  22
  23        let content;
  24        braced!(content in input);
  25
  26        let mut method_visibility = None;
  27
  28        let ident: syn::Ident = content.parse()?;
  29        if ident == "visibility" {
  30            let _colon: Token![:] = content.parse()?;
  31            method_visibility = Some(content.parse()?);
  32        }
  33
  34        Ok(Self {
  35            method_visibility: method_visibility.unwrap_or(Visibility::Inherited),
  36        })
  37    }
  38}
  39
  40pub fn style_helpers(input: TokenStream) -> TokenStream {
  41    let _ = parse_macro_input!(input as StyleableMacroInput);
  42    let methods = generate_methods();
  43    let output = quote! {
  44        #(#methods)*
  45    };
  46
  47    output.into()
  48}
  49
  50pub fn visibility_style_methods(input: TokenStream) -> TokenStream {
  51    let input = parse_macro_input!(input as StyleableMacroInput);
  52    let visibility = input.method_visibility;
  53    let output = quote! {
  54        /// Sets the visibility of the element to `visible`.
  55        /// [Docs](https://tailwindcss.com/docs/visibility)
  56        #visibility fn visible(mut self) -> Self {
  57            self.style().visibility = Some(gpui::Visibility::Visible);
  58            self
  59        }
  60
  61        /// Sets the visibility of the element to `hidden`.
  62        /// [Docs](https://tailwindcss.com/docs/visibility)
  63        #visibility fn invisible(mut self) -> Self {
  64            self.style().visibility = Some(gpui::Visibility::Hidden);
  65            self
  66        }
  67    };
  68
  69    output.into()
  70}
  71
  72pub fn margin_style_methods(input: TokenStream) -> TokenStream {
  73    let input = parse_macro_input!(input as StyleableMacroInput);
  74    let methods = generate_box_style_methods(
  75        margin_box_style_prefixes(),
  76        box_style_suffixes(),
  77        input.method_visibility,
  78    );
  79    let output = quote! {
  80        #(#methods)*
  81    };
  82
  83    output.into()
  84}
  85
  86pub fn padding_style_methods(input: TokenStream) -> TokenStream {
  87    let input = parse_macro_input!(input as StyleableMacroInput);
  88    let methods = generate_box_style_methods(
  89        padding_box_style_prefixes(),
  90        box_style_suffixes(),
  91        input.method_visibility,
  92    );
  93    let output = quote! {
  94        #(#methods)*
  95    };
  96
  97    output.into()
  98}
  99
 100pub fn position_style_methods(input: TokenStream) -> TokenStream {
 101    let input = parse_macro_input!(input as StyleableMacroInput);
 102    let visibility = input.method_visibility;
 103    let methods = generate_box_style_methods(
 104        position_box_style_prefixes(),
 105        box_style_suffixes(),
 106        visibility.clone(),
 107    );
 108    let output = quote! {
 109        /// Sets the position of the element to `relative`.
 110        /// [Docs](https://tailwindcss.com/docs/position)
 111        #visibility fn relative(mut self) -> Self {
 112            self.style().position = Some(gpui::Position::Relative);
 113            self
 114        }
 115
 116        /// Sets the position of the element to `absolute`.
 117        /// [Docs](https://tailwindcss.com/docs/position)
 118        #visibility fn absolute(mut self) -> Self {
 119            self.style().position = Some(gpui::Position::Absolute);
 120            self
 121        }
 122
 123        #(#methods)*
 124    };
 125
 126    output.into()
 127}
 128
 129pub fn overflow_style_methods(input: TokenStream) -> TokenStream {
 130    let input = parse_macro_input!(input as StyleableMacroInput);
 131    let visibility = input.method_visibility;
 132    let output = quote! {
 133        /// Sets the behavior of content that overflows the container to be hidden.
 134        /// [Docs](https://tailwindcss.com/docs/overflow#hiding-content-that-overflows)
 135        #visibility fn overflow_hidden(mut self) -> Self {
 136            self.style().overflow.x = Some(gpui::Overflow::Hidden);
 137            self.style().overflow.y = Some(gpui::Overflow::Hidden);
 138            self
 139        }
 140
 141        /// Sets the behavior of content that overflows the container on the X axis to be hidden.
 142        /// [Docs](https://tailwindcss.com/docs/overflow#hiding-content-that-overflows)
 143        #visibility fn overflow_x_hidden(mut self) -> Self {
 144            self.style().overflow.x = Some(gpui::Overflow::Hidden);
 145            self
 146        }
 147
 148        /// Sets the behavior of content that overflows the container on the Y axis to be hidden.
 149        /// [Docs](https://tailwindcss.com/docs/overflow#hiding-content-that-overflows)
 150        #visibility fn overflow_y_hidden(mut self) -> Self {
 151            self.style().overflow.y = Some(gpui::Overflow::Hidden);
 152            self
 153        }
 154    };
 155
 156    output.into()
 157}
 158
 159pub fn cursor_style_methods(input: TokenStream) -> TokenStream {
 160    let input = parse_macro_input!(input as StyleableMacroInput);
 161    let visibility = input.method_visibility;
 162    let output = quote! {
 163        /// Set the cursor style when hovering over this element
 164        #visibility fn cursor(mut self, cursor: CursorStyle) -> Self {
 165            self.style().mouse_cursor = Some(cursor);
 166            self
 167        }
 168
 169        /// Sets the cursor style when hovering an element to `default`.
 170        /// [Docs](https://tailwindcss.com/docs/cursor)
 171        #visibility fn cursor_default(mut self) -> Self {
 172            self.style().mouse_cursor = Some(gpui::CursorStyle::Arrow);
 173            self
 174        }
 175
 176        /// Sets the cursor style when hovering an element to `pointer`.
 177        /// [Docs](https://tailwindcss.com/docs/cursor)
 178        #visibility fn cursor_pointer(mut self) -> Self {
 179            self.style().mouse_cursor = Some(gpui::CursorStyle::PointingHand);
 180            self
 181        }
 182
 183        /// Sets cursor style when hovering over an element to `text`.
 184        /// [Docs](https://tailwindcss.com/docs/cursor)
 185        #visibility fn cursor_text(mut self) -> Self {
 186            self.style().mouse_cursor = Some(gpui::CursorStyle::IBeam);
 187            self
 188        }
 189
 190        /// Sets cursor style when hovering over an element to `move`.
 191        /// [Docs](https://tailwindcss.com/docs/cursor)
 192        #visibility fn cursor_move(mut self) -> Self {
 193            self.style().mouse_cursor = Some(gpui::CursorStyle::ClosedHand);
 194            self
 195        }
 196
 197        /// Sets cursor style when hovering over an element to `not-allowed`.
 198        /// [Docs](https://tailwindcss.com/docs/cursor)
 199        #visibility fn cursor_not_allowed(mut self) -> Self {
 200            self.style().mouse_cursor = Some(gpui::CursorStyle::OperationNotAllowed);
 201            self
 202        }
 203
 204        /// Sets cursor style when hovering over an element to `context-menu`.
 205        /// [Docs](https://tailwindcss.com/docs/cursor)
 206        #visibility fn cursor_context_menu(mut self) -> Self {
 207            self.style().mouse_cursor = Some(gpui::CursorStyle::ContextualMenu);
 208            self
 209        }
 210
 211        /// Sets cursor style when hovering over an element to `crosshair`.
 212        /// [Docs](https://tailwindcss.com/docs/cursor)
 213        #visibility fn cursor_crosshair(mut self) -> Self {
 214            self.style().mouse_cursor = Some(gpui::CursorStyle::Crosshair);
 215            self
 216        }
 217
 218        /// Sets cursor style when hovering over an element to `vertical-text`.
 219        /// [Docs](https://tailwindcss.com/docs/cursor)
 220        #visibility fn cursor_vertical_text(mut self) -> Self {
 221            self.style().mouse_cursor = Some(gpui::CursorStyle::IBeamCursorForVerticalLayout);
 222            self
 223        }
 224
 225        /// Sets cursor style when hovering over an element to `alias`.
 226        /// [Docs](https://tailwindcss.com/docs/cursor)
 227        #visibility fn cursor_alias(mut self) -> Self {
 228            self.style().mouse_cursor = Some(gpui::CursorStyle::DragLink);
 229            self
 230        }
 231
 232        /// Sets cursor style when hovering over an element to `copy`.
 233        /// [Docs](https://tailwindcss.com/docs/cursor)
 234        #visibility fn cursor_copy(mut self) -> Self {
 235            self.style().mouse_cursor = Some(gpui::CursorStyle::DragCopy);
 236            self
 237        }
 238
 239        /// Sets cursor style when hovering over an element to `no-drop`.
 240        /// [Docs](https://tailwindcss.com/docs/cursor)
 241        #visibility fn cursor_no_drop(mut self) -> Self {
 242            self.style().mouse_cursor = Some(gpui::CursorStyle::OperationNotAllowed);
 243            self
 244        }
 245
 246        /// Sets cursor style when hovering over an element to `grab`.
 247        /// [Docs](https://tailwindcss.com/docs/cursor)
 248        #visibility fn cursor_grab(mut self) -> Self {
 249            self.style().mouse_cursor = Some(gpui::CursorStyle::OpenHand);
 250            self
 251        }
 252
 253        /// Sets cursor style when hovering over an element to `grabbing`.
 254        /// [Docs](https://tailwindcss.com/docs/cursor)
 255        #visibility fn cursor_grabbing(mut self) -> Self {
 256            self.style().mouse_cursor = Some(gpui::CursorStyle::ClosedHand);
 257            self
 258        }
 259
 260        /// Sets cursor style when hovering over an element to `ew-resize`.
 261        /// [Docs](https://tailwindcss.com/docs/cursor)
 262        #visibility fn cursor_ew_resize(mut self) -> Self {
 263            self.style().mouse_cursor = Some(gpui::CursorStyle::ResizeLeftRight);
 264            self
 265        }
 266
 267        /// Sets cursor style when hovering over an element to `ns-resize`.
 268        /// [Docs](https://tailwindcss.com/docs/cursor)
 269        #visibility fn cursor_ns_resize(mut self) -> Self {
 270            self.style().mouse_cursor = Some(gpui::CursorStyle::ResizeUpDown);
 271            self
 272        }
 273
 274        /// Sets cursor style when hovering over an element to `col-resize`.
 275        /// [Docs](https://tailwindcss.com/docs/cursor)
 276        #visibility fn cursor_col_resize(mut self) -> Self {
 277            self.style().mouse_cursor = Some(gpui::CursorStyle::ResizeColumn);
 278            self
 279        }
 280
 281        /// Sets cursor style when hovering over an element to `row-resize`.
 282        /// [Docs](https://tailwindcss.com/docs/cursor)
 283        #visibility fn cursor_row_resize(mut self) -> Self {
 284            self.style().mouse_cursor = Some(gpui::CursorStyle::ResizeRow);
 285            self
 286        }
 287
 288        /// Sets cursor style when hovering over an element to `n-resize`.
 289        /// [Docs](https://tailwindcss.com/docs/cursor)
 290        #visibility fn cursor_n_resize(mut self) -> Self {
 291            self.style().mouse_cursor = Some(gpui::CursorStyle::ResizeUp);
 292            self
 293        }
 294
 295        /// Sets cursor style when hovering over an element to `e-resize`.
 296        /// [Docs](https://tailwindcss.com/docs/cursor)
 297        #visibility fn cursor_e_resize(mut self) -> Self {
 298            self.style().mouse_cursor = Some(gpui::CursorStyle::ResizeRight);
 299            self
 300        }
 301
 302        /// Sets cursor style when hovering over an element to `s-resize`.
 303        /// [Docs](https://tailwindcss.com/docs/cursor)
 304        #visibility fn cursor_s_resize(mut self) -> Self {
 305            self.style().mouse_cursor = Some(gpui::CursorStyle::ResizeDown);
 306            self
 307        }
 308
 309        /// Sets cursor style when hovering over an element to `w-resize`.
 310        /// [Docs](https://tailwindcss.com/docs/cursor)
 311        #visibility fn cursor_w_resize(mut self) -> Self {
 312            self.style().mouse_cursor = Some(gpui::CursorStyle::ResizeLeft);
 313            self
 314        }
 315    };
 316
 317    output.into()
 318}
 319
 320pub fn box_shadow_style_methods(input: TokenStream) -> TokenStream {
 321    let input = parse_macro_input!(input as StyleableMacroInput);
 322    let visibility = input.method_visibility;
 323    let output = quote! {
 324        /// Sets the box shadow of the element.
 325        /// [Docs](https://tailwindcss.com/docs/box-shadow)
 326        #visibility fn shadow(mut self, shadows: smallvec::SmallVec<[gpui::BoxShadow; 2]>) -> Self {
 327            self.style().box_shadow = Some(shadows);
 328            self
 329        }
 330
 331        /// Clears the box shadow of the element.
 332        /// [Docs](https://tailwindcss.com/docs/box-shadow)
 333        #visibility fn shadow_none(mut self) -> Self {
 334            self.style().box_shadow = Some(Default::default());
 335            self
 336        }
 337
 338        /// Sets the box shadow of the element.
 339        /// [Docs](https://tailwindcss.com/docs/box-shadow)
 340        #visibility fn shadow_sm(mut self) -> Self {
 341            use gpui::{BoxShadow, hsla, point, px};
 342            use smallvec::smallvec;
 343
 344            self.style().box_shadow = Some(smallvec![BoxShadow {
 345                color: hsla(0., 0., 0., 0.05),
 346                offset: point(px(0.), px(1.)),
 347                blur_radius: px(2.),
 348                spread_radius: px(0.),
 349            }]);
 350            self
 351        }
 352
 353        /// Sets the box shadow of the element.
 354        /// [Docs](https://tailwindcss.com/docs/box-shadow)
 355        #visibility fn shadow_md(mut self) -> Self {
 356            use gpui::{BoxShadow, hsla, point, px};
 357            use smallvec::smallvec;
 358
 359            self.style().box_shadow = Some(smallvec![
 360                BoxShadow {
 361                    color: hsla(0.5, 0., 0., 0.1),
 362                    offset: point(px(0.), px(4.)),
 363                    blur_radius: px(6.),
 364                    spread_radius: px(-1.),
 365                },
 366                BoxShadow {
 367                    color: hsla(0., 0., 0., 0.1),
 368                    offset: point(px(0.), px(2.)),
 369                    blur_radius: px(4.),
 370                    spread_radius: px(-2.),
 371                }
 372            ]);
 373            self
 374        }
 375
 376        /// Sets the box shadow of the element.
 377        /// [Docs](https://tailwindcss.com/docs/box-shadow)
 378        #visibility fn shadow_lg(mut self) -> Self {
 379            use gpui::{BoxShadow, hsla, point, px};
 380            use smallvec::smallvec;
 381
 382            self.style().box_shadow = Some(smallvec![
 383                BoxShadow {
 384                    color: hsla(0., 0., 0., 0.1),
 385                    offset: point(px(0.), px(10.)),
 386                    blur_radius: px(15.),
 387                    spread_radius: px(-3.),
 388                },
 389                BoxShadow {
 390                    color: hsla(0., 0., 0., 0.1),
 391                    offset: point(px(0.), px(4.)),
 392                    blur_radius: px(6.),
 393                    spread_radius: px(-4.),
 394                }
 395            ]);
 396            self
 397        }
 398
 399        /// Sets the box shadow of the element.
 400        /// [Docs](https://tailwindcss.com/docs/box-shadow)
 401        #visibility fn shadow_xl(mut self) -> Self {
 402            use gpui::{BoxShadow, hsla, point, px};
 403            use smallvec::smallvec;
 404
 405            self.style().box_shadow = Some(smallvec![
 406                BoxShadow {
 407                    color: hsla(0., 0., 0., 0.1),
 408                    offset: point(px(0.), px(20.)),
 409                    blur_radius: px(25.),
 410                    spread_radius: px(-5.),
 411                },
 412                BoxShadow {
 413                    color: hsla(0., 0., 0., 0.1),
 414                    offset: point(px(0.), px(8.)),
 415                    blur_radius: px(10.),
 416                    spread_radius: px(-6.),
 417                }
 418            ]);
 419            self
 420        }
 421
 422        /// Sets the box shadow of the element.
 423        /// [Docs](https://tailwindcss.com/docs/box-shadow)
 424        #visibility fn shadow_2xl(mut self) -> Self {
 425            use gpui::{BoxShadow, hsla, point, px};
 426            use smallvec::smallvec;
 427
 428            self.style().box_shadow = Some(smallvec![BoxShadow {
 429                color: hsla(0., 0., 0., 0.25),
 430                offset: point(px(0.), px(25.)),
 431                blur_radius: px(50.),
 432                spread_radius: px(-12.),
 433            }]);
 434            self
 435        }
 436    };
 437
 438    output.into()
 439}
 440
 441struct BoxStylePrefix {
 442    prefix: &'static str,
 443    auto_allowed: bool,
 444    fields: Vec<TokenStream2>,
 445    doc_string_prefix: &'static str,
 446}
 447
 448struct BoxStyleSuffix {
 449    suffix: &'static str,
 450    length_tokens: TokenStream2,
 451    doc_string_suffix: &'static str,
 452}
 453
 454struct CornerStylePrefix {
 455    prefix: &'static str,
 456    fields: Vec<TokenStream2>,
 457    doc_string_prefix: &'static str,
 458}
 459
 460struct CornerStyleSuffix {
 461    suffix: &'static str,
 462    radius_tokens: TokenStream2,
 463    doc_string_suffix: &'static str,
 464}
 465
 466struct BorderStylePrefix {
 467    prefix: &'static str,
 468    fields: Vec<TokenStream2>,
 469    doc_string_prefix: &'static str,
 470}
 471
 472struct BorderStyleSuffix {
 473    suffix: &'static str,
 474    width_tokens: TokenStream2,
 475    doc_string_suffix: &'static str,
 476}
 477
 478fn generate_box_style_methods(
 479    prefixes: Vec<BoxStylePrefix>,
 480    suffixes: Vec<BoxStyleSuffix>,
 481    visibility: Visibility,
 482) -> Vec<TokenStream2> {
 483    let mut methods = Vec::new();
 484
 485    for box_style_prefix in prefixes {
 486        methods.push(generate_custom_value_setter(
 487            visibility.clone(),
 488            box_style_prefix.prefix,
 489            if box_style_prefix.auto_allowed {
 490                quote! { Length }
 491            } else {
 492                quote! { DefiniteLength }
 493            },
 494            &box_style_prefix.fields,
 495            &box_style_prefix.doc_string_prefix,
 496        ));
 497
 498        for box_style_suffix in &suffixes {
 499            if box_style_suffix.suffix != "auto" || box_style_prefix.auto_allowed {
 500                methods.push(generate_predefined_setter(
 501                    visibility.clone(),
 502                    box_style_prefix.prefix,
 503                    box_style_suffix.suffix,
 504                    &box_style_prefix.fields,
 505                    &box_style_suffix.length_tokens,
 506                    false,
 507                    &format!(
 508                        "{prefix}\n\n{suffix}",
 509                        prefix = box_style_prefix.doc_string_prefix,
 510                        suffix = box_style_suffix.doc_string_suffix,
 511                    ),
 512                ));
 513            }
 514
 515            if box_style_suffix.suffix != "auto" {
 516                methods.push(generate_predefined_setter(
 517                    visibility.clone(),
 518                    box_style_prefix.prefix,
 519                    box_style_suffix.suffix,
 520                    &box_style_prefix.fields,
 521                    &box_style_suffix.length_tokens,
 522                    true,
 523                    &format!(
 524                        "{prefix}\n\n{suffix}",
 525                        prefix = box_style_prefix.doc_string_prefix,
 526                        suffix = box_style_suffix.doc_string_suffix,
 527                    ),
 528                ));
 529            }
 530        }
 531    }
 532
 533    methods
 534}
 535
 536fn generate_methods() -> Vec<TokenStream2> {
 537    let visibility = Visibility::Inherited;
 538    let mut methods =
 539        generate_box_style_methods(box_prefixes(), box_style_suffixes(), visibility.clone());
 540
 541    for corner_style_prefix in corner_prefixes() {
 542        methods.push(generate_custom_value_setter(
 543            visibility.clone(),
 544            corner_style_prefix.prefix,
 545            quote! { AbsoluteLength },
 546            &corner_style_prefix.fields,
 547            corner_style_prefix.doc_string_prefix,
 548        ));
 549
 550        for corner_style_suffix in corner_suffixes() {
 551            methods.push(generate_predefined_setter(
 552                visibility.clone(),
 553                corner_style_prefix.prefix,
 554                corner_style_suffix.suffix,
 555                &corner_style_prefix.fields,
 556                &corner_style_suffix.radius_tokens,
 557                false,
 558                &format!(
 559                    "{prefix}\n\n{suffix}",
 560                    prefix = corner_style_prefix.doc_string_prefix,
 561                    suffix = corner_style_suffix.doc_string_suffix,
 562                ),
 563            ));
 564        }
 565    }
 566
 567    for border_style_prefix in border_prefixes() {
 568        methods.push(generate_custom_value_setter(
 569            visibility.clone(),
 570            border_style_prefix.prefix,
 571            quote! { AbsoluteLength },
 572            &border_style_prefix.fields,
 573            border_style_prefix.doc_string_prefix,
 574        ));
 575
 576        for border_style_suffix in border_suffixes() {
 577            methods.push(generate_predefined_setter(
 578                visibility.clone(),
 579                border_style_prefix.prefix,
 580                border_style_suffix.suffix,
 581                &border_style_prefix.fields,
 582                &border_style_suffix.width_tokens,
 583                false,
 584                &format!(
 585                    "{prefix}\n\n{suffix}",
 586                    prefix = border_style_prefix.doc_string_prefix,
 587                    suffix = border_style_suffix.doc_string_suffix,
 588                ),
 589            ));
 590        }
 591    }
 592    methods
 593}
 594
 595fn generate_predefined_setter(
 596    visibility: Visibility,
 597    name: &'static str,
 598    length: &'static str,
 599    fields: &[TokenStream2],
 600    length_tokens: &TokenStream2,
 601    negate: bool,
 602    doc_string: &str,
 603) -> TokenStream2 {
 604    let (negation_qualifier, negation_token) = if negate {
 605        ("_neg", quote! { - })
 606    } else {
 607        ("", quote! {})
 608    };
 609
 610    let method_name = if length.is_empty() {
 611        format_ident!("{name}{negation_qualifier}")
 612    } else {
 613        format_ident!("{name}{negation_qualifier}_{length}")
 614    };
 615
 616    let field_assignments = fields
 617        .iter()
 618        .map(|field_tokens| {
 619            quote! {
 620                style.#field_tokens = Some((#negation_token gpui::#length_tokens).into());
 621            }
 622        })
 623        .collect::<Vec<_>>();
 624
 625    let method = quote! {
 626        #[doc = #doc_string]
 627        #visibility fn #method_name(mut self) -> Self {
 628            let style = self.style();
 629            #(#field_assignments)*
 630            self
 631        }
 632    };
 633
 634    method
 635}
 636
 637fn generate_custom_value_setter(
 638    visibility: Visibility,
 639    prefix: &str,
 640    length_type: TokenStream2,
 641    fields: &[TokenStream2],
 642    doc_string: &str,
 643) -> TokenStream2 {
 644    let method_name = format_ident!("{}", prefix);
 645
 646    let mut iter = fields.iter();
 647    let last = iter.next_back().unwrap();
 648    let field_assignments = iter
 649        .map(|field_tokens| {
 650            quote! {
 651                style.#field_tokens = Some(length.clone().into());
 652            }
 653        })
 654        .chain(std::iter::once(quote! {
 655            style.#last = Some(length.into());
 656        }))
 657        .collect::<Vec<_>>();
 658
 659    let method = quote! {
 660        #[doc = #doc_string]
 661        #visibility fn #method_name(mut self, length: impl std::clone::Clone + Into<gpui::#length_type>) -> Self {
 662            let style = self.style();
 663            #(#field_assignments)*
 664            self
 665        }
 666    };
 667
 668    method
 669}
 670
 671fn margin_box_style_prefixes() -> Vec<BoxStylePrefix> {
 672    vec![
 673        BoxStylePrefix {
 674            prefix: "m",
 675            auto_allowed: true,
 676            fields: vec![
 677                quote! { margin.top },
 678                quote! { margin.bottom },
 679                quote! { margin.left },
 680                quote! { margin.right },
 681            ],
 682            doc_string_prefix: "Sets the margin of the element. [Docs](https://tailwindcss.com/docs/margin)",
 683        },
 684        BoxStylePrefix {
 685            prefix: "mt",
 686            auto_allowed: true,
 687            fields: vec![quote! { margin.top }],
 688            doc_string_prefix: "Sets the top margin of the element. [Docs](https://tailwindcss.com/docs/margin#add-margin-to-a-single-side)",
 689        },
 690        BoxStylePrefix {
 691            prefix: "mb",
 692            auto_allowed: true,
 693            fields: vec![quote! { margin.bottom }],
 694            doc_string_prefix: "Sets the bottom margin of the element. [Docs](https://tailwindcss.com/docs/margin#add-margin-to-a-single-side)",
 695        },
 696        BoxStylePrefix {
 697            prefix: "my",
 698            auto_allowed: true,
 699            fields: vec![quote! { margin.top }, quote! { margin.bottom }],
 700            doc_string_prefix: "Sets the vertical margin of the element. [Docs](https://tailwindcss.com/docs/margin#add-vertical-margin)",
 701        },
 702        BoxStylePrefix {
 703            prefix: "mx",
 704            auto_allowed: true,
 705            fields: vec![quote! { margin.left }, quote! { margin.right }],
 706            doc_string_prefix: "Sets the horizontal margin of the element. [Docs](https://tailwindcss.com/docs/margin#add-horizontal-margin)",
 707        },
 708        BoxStylePrefix {
 709            prefix: "ml",
 710            auto_allowed: true,
 711            fields: vec![quote! { margin.left }],
 712            doc_string_prefix: "Sets the left margin of the element. [Docs](https://tailwindcss.com/docs/margin#add-margin-to-a-single-side)",
 713        },
 714        BoxStylePrefix {
 715            prefix: "mr",
 716            auto_allowed: true,
 717            fields: vec![quote! { margin.right }],
 718            doc_string_prefix: "Sets the right margin of the element. [Docs](https://tailwindcss.com/docs/margin#add-margin-to-a-single-side)",
 719        },
 720    ]
 721}
 722
 723fn padding_box_style_prefixes() -> Vec<BoxStylePrefix> {
 724    vec![
 725        BoxStylePrefix {
 726            prefix: "p",
 727            auto_allowed: false,
 728            fields: vec![
 729                quote! { padding.top },
 730                quote! { padding.bottom },
 731                quote! { padding.left },
 732                quote! { padding.right },
 733            ],
 734            doc_string_prefix: "Sets the padding of the element. [Docs](https://tailwindcss.com/docs/padding)",
 735        },
 736        BoxStylePrefix {
 737            prefix: "pt",
 738            auto_allowed: false,
 739            fields: vec![quote! { padding.top }],
 740            doc_string_prefix: "Sets the top padding of the element. [Docs](https://tailwindcss.com/docs/padding#add-padding-to-a-single-side)",
 741        },
 742        BoxStylePrefix {
 743            prefix: "pb",
 744            auto_allowed: false,
 745            fields: vec![quote! { padding.bottom }],
 746            doc_string_prefix: "Sets the bottom padding of the element. [Docs](https://tailwindcss.com/docs/padding#add-padding-to-a-single-side)",
 747        },
 748        BoxStylePrefix {
 749            prefix: "px",
 750            auto_allowed: false,
 751            fields: vec![quote! { padding.left }, quote! { padding.right }],
 752            doc_string_prefix: "Sets the horizontal padding of the element. [Docs](https://tailwindcss.com/docs/padding#add-horizontal-padding)",
 753        },
 754        BoxStylePrefix {
 755            prefix: "py",
 756            auto_allowed: false,
 757            fields: vec![quote! { padding.top }, quote! { padding.bottom }],
 758            doc_string_prefix: "Sets the vertical padding of the element. [Docs](https://tailwindcss.com/docs/padding#add-vertical-padding)",
 759        },
 760        BoxStylePrefix {
 761            prefix: "pl",
 762            auto_allowed: false,
 763            fields: vec![quote! { padding.left }],
 764            doc_string_prefix: "Sets the left padding of the element. [Docs](https://tailwindcss.com/docs/padding#add-padding-to-a-single-side)",
 765        },
 766        BoxStylePrefix {
 767            prefix: "pr",
 768            auto_allowed: false,
 769            fields: vec![quote! { padding.right }],
 770            doc_string_prefix: "Sets the right padding of the element. [Docs](https://tailwindcss.com/docs/padding#add-padding-to-a-single-side)",
 771        },
 772    ]
 773}
 774
 775fn position_box_style_prefixes() -> Vec<BoxStylePrefix> {
 776    vec![
 777        BoxStylePrefix {
 778            prefix: "inset",
 779            auto_allowed: true,
 780            fields: vec![
 781                quote! { inset.top },
 782                quote! { inset.right },
 783                quote! { inset.bottom },
 784                quote! { inset.left },
 785            ],
 786            doc_string_prefix: "Sets the top, right, bottom, and left values of a positioned element. [Docs](https://tailwindcss.com/docs/top-right-bottom-left)",
 787        },
 788        BoxStylePrefix {
 789            prefix: "top",
 790            auto_allowed: true,
 791            fields: vec![quote! { inset.top }],
 792            doc_string_prefix: "Sets the top value of a positioned element. [Docs](https://tailwindcss.com/docs/top-right-bottom-left)",
 793        },
 794        BoxStylePrefix {
 795            prefix: "bottom",
 796            auto_allowed: true,
 797            fields: vec![quote! { inset.bottom }],
 798            doc_string_prefix: "Sets the bottom value of a positioned element. [Docs](https://tailwindcss.com/docs/top-right-bottom-left)",
 799        },
 800        BoxStylePrefix {
 801            prefix: "left",
 802            auto_allowed: true,
 803            fields: vec![quote! { inset.left }],
 804            doc_string_prefix: "Sets the left value of a positioned element. [Docs](https://tailwindcss.com/docs/top-right-bottom-left)",
 805        },
 806        BoxStylePrefix {
 807            prefix: "right",
 808            auto_allowed: true,
 809            fields: vec![quote! { inset.right }],
 810            doc_string_prefix: "Sets the right value of a positioned element. [Docs](https://tailwindcss.com/docs/top-right-bottom-left)",
 811        },
 812    ]
 813}
 814
 815fn box_prefixes() -> Vec<BoxStylePrefix> {
 816    vec![
 817        BoxStylePrefix {
 818            prefix: "w",
 819            auto_allowed: true,
 820            fields: vec![quote! { size.width }],
 821            doc_string_prefix: "Sets the width of the element. [Docs](https://tailwindcss.com/docs/width)",
 822        },
 823        BoxStylePrefix {
 824            prefix: "h",
 825            auto_allowed: true,
 826            fields: vec![quote! { size.height }],
 827            doc_string_prefix: "Sets the height of the element. [Docs](https://tailwindcss.com/docs/height)",
 828        },
 829        BoxStylePrefix {
 830            prefix: "size",
 831            auto_allowed: true,
 832            fields: vec![quote! {size.width}, quote! {size.height}],
 833            doc_string_prefix: "Sets the width and height of the element.",
 834        },
 835        // TODO: These don't use the same size ramp as the others
 836        // see https://tailwindcss.com/docs/max-width
 837        BoxStylePrefix {
 838            prefix: "min_w",
 839            auto_allowed: true,
 840            fields: vec![quote! { min_size.width }],
 841            doc_string_prefix: "Sets the minimum width of the element. [Docs](https://tailwindcss.com/docs/min-width)",
 842        },
 843        // TODO: These don't use the same size ramp as the others
 844        // see https://tailwindcss.com/docs/max-width
 845        BoxStylePrefix {
 846            prefix: "min_h",
 847            auto_allowed: true,
 848            fields: vec![quote! { min_size.height }],
 849            doc_string_prefix: "Sets the minimum height of the element. [Docs](https://tailwindcss.com/docs/min-height)",
 850        },
 851        // TODO: These don't use the same size ramp as the others
 852        // see https://tailwindcss.com/docs/max-width
 853        BoxStylePrefix {
 854            prefix: "max_w",
 855            auto_allowed: true,
 856            fields: vec![quote! { max_size.width }],
 857            doc_string_prefix: "Sets the maximum width of the element. [Docs](https://tailwindcss.com/docs/max-width)",
 858        },
 859        // TODO: These don't use the same size ramp as the others
 860        // see https://tailwindcss.com/docs/max-width
 861        BoxStylePrefix {
 862            prefix: "max_h",
 863            auto_allowed: true,
 864            fields: vec![quote! { max_size.height }],
 865            doc_string_prefix: "Sets the maximum height of the element. [Docs](https://tailwindcss.com/docs/max-height)",
 866        },
 867        BoxStylePrefix {
 868            prefix: "gap",
 869            auto_allowed: false,
 870            fields: vec![quote! { gap.width }, quote! { gap.height }],
 871            doc_string_prefix: "Sets the gap between rows and columns in flex layouts. [Docs](https://tailwindcss.com/docs/gap)",
 872        },
 873        BoxStylePrefix {
 874            prefix: "gap_x",
 875            auto_allowed: false,
 876            fields: vec![quote! { gap.width }],
 877            doc_string_prefix: "Sets the gap between columns in flex layouts. [Docs](https://tailwindcss.com/docs/gap#changing-row-and-column-gaps-independently)",
 878        },
 879        BoxStylePrefix {
 880            prefix: "gap_y",
 881            auto_allowed: false,
 882            fields: vec![quote! { gap.height }],
 883            doc_string_prefix: "Sets the gap between rows in flex layouts. [Docs](https://tailwindcss.com/docs/gap#changing-row-and-column-gaps-independently)",
 884        },
 885    ]
 886}
 887
 888fn box_style_suffixes() -> Vec<BoxStyleSuffix> {
 889    vec![
 890        BoxStyleSuffix {
 891            suffix: "0",
 892            length_tokens: quote! { px(0.) },
 893            doc_string_suffix: "0px",
 894        },
 895        BoxStyleSuffix {
 896            suffix: "0p5",
 897            length_tokens: quote! { rems(0.125) },
 898            doc_string_suffix: "2px (0.125rem)",
 899        },
 900        BoxStyleSuffix {
 901            suffix: "1",
 902            length_tokens: quote! { rems(0.25) },
 903            doc_string_suffix: "4px (0.25rem)",
 904        },
 905        BoxStyleSuffix {
 906            suffix: "1p5",
 907            length_tokens: quote! { rems(0.375) },
 908            doc_string_suffix: "6px (0.375rem)",
 909        },
 910        BoxStyleSuffix {
 911            suffix: "2",
 912            length_tokens: quote! { rems(0.5) },
 913            doc_string_suffix: "8px (0.5rem)",
 914        },
 915        BoxStyleSuffix {
 916            suffix: "2p5",
 917            length_tokens: quote! { rems(0.625) },
 918            doc_string_suffix: "10px (0.625rem)",
 919        },
 920        BoxStyleSuffix {
 921            suffix: "3",
 922            length_tokens: quote! { rems(0.75) },
 923            doc_string_suffix: "12px (0.75rem)",
 924        },
 925        BoxStyleSuffix {
 926            suffix: "3p5",
 927            length_tokens: quote! { rems(0.875) },
 928            doc_string_suffix: "14px (0.875rem)",
 929        },
 930        BoxStyleSuffix {
 931            suffix: "4",
 932            length_tokens: quote! { rems(1.) },
 933            doc_string_suffix: "16px (1rem)",
 934        },
 935        BoxStyleSuffix {
 936            suffix: "5",
 937            length_tokens: quote! { rems(1.25) },
 938            doc_string_suffix: "20px (1.25rem)",
 939        },
 940        BoxStyleSuffix {
 941            suffix: "6",
 942            length_tokens: quote! { rems(1.5) },
 943            doc_string_suffix: "24px (1.5rem)",
 944        },
 945        BoxStyleSuffix {
 946            suffix: "7",
 947            length_tokens: quote! { rems(1.75) },
 948            doc_string_suffix: "28px (1.75rem)",
 949        },
 950        BoxStyleSuffix {
 951            suffix: "8",
 952            length_tokens: quote! { rems(2.0) },
 953            doc_string_suffix: "32px (2rem)",
 954        },
 955        BoxStyleSuffix {
 956            suffix: "9",
 957            length_tokens: quote! { rems(2.25) },
 958            doc_string_suffix: "36px (2.25rem)",
 959        },
 960        BoxStyleSuffix {
 961            suffix: "10",
 962            length_tokens: quote! { rems(2.5) },
 963            doc_string_suffix: "40px (2.5rem)",
 964        },
 965        BoxStyleSuffix {
 966            suffix: "11",
 967            length_tokens: quote! { rems(2.75) },
 968            doc_string_suffix: "44px (2.75rem)",
 969        },
 970        BoxStyleSuffix {
 971            suffix: "12",
 972            length_tokens: quote! { rems(3.) },
 973            doc_string_suffix: "48px (3rem)",
 974        },
 975        BoxStyleSuffix {
 976            suffix: "16",
 977            length_tokens: quote! { rems(4.) },
 978            doc_string_suffix: "64px (4rem)",
 979        },
 980        BoxStyleSuffix {
 981            suffix: "20",
 982            length_tokens: quote! { rems(5.) },
 983            doc_string_suffix: "80px (5rem)",
 984        },
 985        BoxStyleSuffix {
 986            suffix: "24",
 987            length_tokens: quote! { rems(6.) },
 988            doc_string_suffix: "96px (6rem)",
 989        },
 990        BoxStyleSuffix {
 991            suffix: "32",
 992            length_tokens: quote! { rems(8.) },
 993            doc_string_suffix: "128px (8rem)",
 994        },
 995        BoxStyleSuffix {
 996            suffix: "40",
 997            length_tokens: quote! { rems(10.) },
 998            doc_string_suffix: "160px (10rem)",
 999        },
1000        BoxStyleSuffix {
1001            suffix: "48",
1002            length_tokens: quote! { rems(12.) },
1003            doc_string_suffix: "192px (12rem)",
1004        },
1005        BoxStyleSuffix {
1006            suffix: "56",
1007            length_tokens: quote! { rems(14.) },
1008            doc_string_suffix: "224px (14rem)",
1009        },
1010        BoxStyleSuffix {
1011            suffix: "64",
1012            length_tokens: quote! { rems(16.) },
1013            doc_string_suffix: "256px (16rem)",
1014        },
1015        BoxStyleSuffix {
1016            suffix: "72",
1017            length_tokens: quote! { rems(18.) },
1018            doc_string_suffix: "288px (18rem)",
1019        },
1020        BoxStyleSuffix {
1021            suffix: "80",
1022            length_tokens: quote! { rems(20.) },
1023            doc_string_suffix: "320px (20rem)",
1024        },
1025        BoxStyleSuffix {
1026            suffix: "96",
1027            length_tokens: quote! { rems(24.) },
1028            doc_string_suffix: "384px (24rem)",
1029        },
1030        BoxStyleSuffix {
1031            suffix: "112",
1032            length_tokens: quote! { rems(28.) },
1033            doc_string_suffix: "448px (28rem)",
1034        },
1035        BoxStyleSuffix {
1036            suffix: "128",
1037            length_tokens: quote! { rems(32.) },
1038            doc_string_suffix: "512px (32rem)",
1039        },
1040        BoxStyleSuffix {
1041            suffix: "auto",
1042            length_tokens: quote! { auto() },
1043            doc_string_suffix: "Auto",
1044        },
1045        BoxStyleSuffix {
1046            suffix: "px",
1047            length_tokens: quote! { px(1.) },
1048            doc_string_suffix: "1px",
1049        },
1050        BoxStyleSuffix {
1051            suffix: "full",
1052            length_tokens: quote! { relative(1.) },
1053            doc_string_suffix: "100%",
1054        },
1055        BoxStyleSuffix {
1056            suffix: "1_2",
1057            length_tokens: quote! { relative(0.5) },
1058            doc_string_suffix: "50% (1/2)",
1059        },
1060        BoxStyleSuffix {
1061            suffix: "1_3",
1062            length_tokens: quote! { relative(1./3.) },
1063            doc_string_suffix: "33% (1/3)",
1064        },
1065        BoxStyleSuffix {
1066            suffix: "2_3",
1067            length_tokens: quote! { relative(2./3.) },
1068            doc_string_suffix: "66% (2/3)",
1069        },
1070        BoxStyleSuffix {
1071            suffix: "1_4",
1072            length_tokens: quote! { relative(0.25) },
1073            doc_string_suffix: "25% (1/4)",
1074        },
1075        BoxStyleSuffix {
1076            suffix: "2_4",
1077            length_tokens: quote! { relative(0.5) },
1078            doc_string_suffix: "50% (2/4)",
1079        },
1080        BoxStyleSuffix {
1081            suffix: "3_4",
1082            length_tokens: quote! { relative(0.75) },
1083            doc_string_suffix: "75% (3/4)",
1084        },
1085        BoxStyleSuffix {
1086            suffix: "1_5",
1087            length_tokens: quote! { relative(0.2) },
1088            doc_string_suffix: "20% (1/5)",
1089        },
1090        BoxStyleSuffix {
1091            suffix: "2_5",
1092            length_tokens: quote! { relative(0.4) },
1093            doc_string_suffix: "40% (2/5)",
1094        },
1095        BoxStyleSuffix {
1096            suffix: "3_5",
1097            length_tokens: quote! { relative(0.6) },
1098            doc_string_suffix: "60% (3/5)",
1099        },
1100        BoxStyleSuffix {
1101            suffix: "4_5",
1102            length_tokens: quote! { relative(0.8) },
1103            doc_string_suffix: "80% (4/5)",
1104        },
1105        BoxStyleSuffix {
1106            suffix: "1_6",
1107            length_tokens: quote! { relative(1./6.) },
1108            doc_string_suffix: "16% (1/6)",
1109        },
1110        BoxStyleSuffix {
1111            suffix: "5_6",
1112            length_tokens: quote! { relative(5./6.) },
1113            doc_string_suffix: "80% (5/6)",
1114        },
1115        BoxStyleSuffix {
1116            suffix: "1_12",
1117            length_tokens: quote! { relative(1./12.) },
1118            doc_string_suffix: "8% (1/12)",
1119        },
1120    ]
1121}
1122
1123fn corner_prefixes() -> Vec<CornerStylePrefix> {
1124    vec![
1125        CornerStylePrefix {
1126            prefix: "rounded",
1127            fields: vec![
1128                quote! { corner_radii.top_left },
1129                quote! { corner_radii.top_right },
1130                quote! { corner_radii.bottom_right },
1131                quote! { corner_radii.bottom_left },
1132            ],
1133            doc_string_prefix: "Sets the border radius of the element. [Docs](https://tailwindcss.com/docs/border-radius)",
1134        },
1135        CornerStylePrefix {
1136            prefix: "rounded_t",
1137            fields: vec![
1138                quote! { corner_radii.top_left },
1139                quote! { corner_radii.top_right },
1140            ],
1141            doc_string_prefix: "Sets the border radius of the top side of the element. [Docs](https://tailwindcss.com/docs/border-radius#rounding-sides-separately)",
1142        },
1143        CornerStylePrefix {
1144            prefix: "rounded_b",
1145            fields: vec![
1146                quote! { corner_radii.bottom_left },
1147                quote! { corner_radii.bottom_right },
1148            ],
1149            doc_string_prefix: "Sets the border radius of the bottom side of the element. [Docs](https://tailwindcss.com/docs/border-radius#rounding-sides-separately)",
1150        },
1151        CornerStylePrefix {
1152            prefix: "rounded_r",
1153            fields: vec![
1154                quote! { corner_radii.top_right },
1155                quote! { corner_radii.bottom_right },
1156            ],
1157            doc_string_prefix: "Sets the border radius of the right side of the element. [Docs](https://tailwindcss.com/docs/border-radius#rounding-sides-separately)",
1158        },
1159        CornerStylePrefix {
1160            prefix: "rounded_l",
1161            fields: vec![
1162                quote! { corner_radii.top_left },
1163                quote! { corner_radii.bottom_left },
1164            ],
1165            doc_string_prefix: "Sets the border radius of the left side of the element. [Docs](https://tailwindcss.com/docs/border-radius#rounding-sides-separately)",
1166        },
1167        CornerStylePrefix {
1168            prefix: "rounded_tl",
1169            fields: vec![quote! { corner_radii.top_left }],
1170            doc_string_prefix: "Sets the border radius of the top left corner of the element. [Docs](https://tailwindcss.com/docs/border-radius#rounding-corners-separately)",
1171        },
1172        CornerStylePrefix {
1173            prefix: "rounded_tr",
1174            fields: vec![quote! { corner_radii.top_right }],
1175            doc_string_prefix: "Sets the border radius of the top right corner of the element. [Docs](https://tailwindcss.com/docs/border-radius#rounding-corners-separately)",
1176        },
1177        CornerStylePrefix {
1178            prefix: "rounded_bl",
1179            fields: vec![quote! { corner_radii.bottom_left }],
1180            doc_string_prefix: "Sets the border radius of the bottom left corner of the element. [Docs](https://tailwindcss.com/docs/border-radius#rounding-corners-separately)",
1181        },
1182        CornerStylePrefix {
1183            prefix: "rounded_br",
1184            fields: vec![quote! { corner_radii.bottom_right }],
1185            doc_string_prefix: "Sets the border radius of the bottom right corner of the element. [Docs](https://tailwindcss.com/docs/border-radius#rounding-corners-separately)",
1186        },
1187    ]
1188}
1189
1190fn corner_suffixes() -> Vec<CornerStyleSuffix> {
1191    vec![
1192        CornerStyleSuffix {
1193            suffix: "none",
1194            radius_tokens: quote! { px(0.) },
1195            doc_string_suffix: "0px",
1196        },
1197        CornerStyleSuffix {
1198            suffix: "sm",
1199            radius_tokens: quote! { rems(0.125) },
1200            doc_string_suffix: "2px (0.125rem)",
1201        },
1202        CornerStyleSuffix {
1203            suffix: "md",
1204            radius_tokens: quote! { rems(0.25) },
1205            doc_string_suffix: "4px (0.25rem)",
1206        },
1207        CornerStyleSuffix {
1208            suffix: "lg",
1209            radius_tokens: quote! { rems(0.5) },
1210            doc_string_suffix: "8px (0.5rem)",
1211        },
1212        CornerStyleSuffix {
1213            suffix: "xl",
1214            radius_tokens: quote! { rems(0.75) },
1215            doc_string_suffix: "12px (0.75rem)",
1216        },
1217        CornerStyleSuffix {
1218            suffix: "2xl",
1219            radius_tokens: quote! { rems(1.) },
1220            doc_string_suffix: "16px (1rem)",
1221        },
1222        CornerStyleSuffix {
1223            suffix: "3xl",
1224            radius_tokens: quote! { rems(1.5) },
1225            doc_string_suffix: "24px (1.5rem)",
1226        },
1227        CornerStyleSuffix {
1228            suffix: "full",
1229            radius_tokens: quote! {  px(9999.) },
1230            doc_string_suffix: "9999px",
1231        },
1232    ]
1233}
1234
1235fn border_prefixes() -> Vec<BorderStylePrefix> {
1236    vec![
1237        BorderStylePrefix {
1238            prefix: "border",
1239            fields: vec![
1240                quote! { border_widths.top },
1241                quote! { border_widths.right },
1242                quote! { border_widths.bottom },
1243                quote! { border_widths.left },
1244            ],
1245            doc_string_prefix: "Sets the border width of the element. [Docs](https://tailwindcss.com/docs/border-width)"
1246        },
1247        BorderStylePrefix {
1248            prefix: "border_t",
1249            fields: vec![quote! { border_widths.top }],
1250            doc_string_prefix: "Sets the border width of the top side of the element. [Docs](https://tailwindcss.com/docs/border-width#individual-sides)"
1251        },
1252        BorderStylePrefix {
1253            prefix: "border_b",
1254            fields: vec![quote! { border_widths.bottom }],
1255            doc_string_prefix: "Sets the border width of the bottom side of the element. [Docs](https://tailwindcss.com/docs/border-width#individual-sides)"
1256        },
1257        BorderStylePrefix {
1258            prefix: "border_r",
1259            fields: vec![quote! { border_widths.right }],
1260            doc_string_prefix: "Sets the border width of the right side of the element. [Docs](https://tailwindcss.com/docs/border-width#individual-sides)"
1261        },
1262        BorderStylePrefix {
1263            prefix: "border_l",
1264            fields: vec![quote! { border_widths.left }],
1265            doc_string_prefix: "Sets the border width of the left side of the element. [Docs](https://tailwindcss.com/docs/border-width#individual-sides)"
1266        },
1267        BorderStylePrefix {
1268            prefix: "border_x",
1269            fields: vec![
1270                quote! { border_widths.left },
1271                quote! { border_widths.right },
1272            ],
1273            doc_string_prefix: "Sets the border width of the vertical sides of the element. [Docs](https://tailwindcss.com/docs/border-width#horizontal-and-vertical-sides)"
1274        },
1275        BorderStylePrefix {
1276            prefix: "border_y",
1277            fields: vec![
1278                quote! { border_widths.top },
1279                quote! { border_widths.bottom },
1280            ],
1281            doc_string_prefix: "Sets the border width of the horizontal sides of the element. [Docs](https://tailwindcss.com/docs/border-width#horizontal-and-vertical-sides)"
1282        },
1283    ]
1284}
1285
1286fn border_suffixes() -> Vec<BorderStyleSuffix> {
1287    vec![
1288        BorderStyleSuffix {
1289            suffix: "0",
1290            width_tokens: quote! { px(0.)},
1291            doc_string_suffix: "0px",
1292        },
1293        BorderStyleSuffix {
1294            suffix: "1",
1295            width_tokens: quote! { px(1.) },
1296            doc_string_suffix: "1px",
1297        },
1298        BorderStyleSuffix {
1299            suffix: "2",
1300            width_tokens: quote! { px(2.) },
1301            doc_string_suffix: "2px",
1302        },
1303        BorderStyleSuffix {
1304            suffix: "3",
1305            width_tokens: quote! { px(3.) },
1306            doc_string_suffix: "3px",
1307        },
1308        BorderStyleSuffix {
1309            suffix: "4",
1310            width_tokens: quote! { px(4.) },
1311            doc_string_suffix: "4px",
1312        },
1313        BorderStyleSuffix {
1314            suffix: "5",
1315            width_tokens: quote! { px(5.) },
1316            doc_string_suffix: "5px",
1317        },
1318        BorderStyleSuffix {
1319            suffix: "6",
1320            width_tokens: quote! { px(6.) },
1321            doc_string_suffix: "6px",
1322        },
1323        BorderStyleSuffix {
1324            suffix: "7",
1325            width_tokens: quote! { px(7.) },
1326            doc_string_suffix: "7px",
1327        },
1328        BorderStyleSuffix {
1329            suffix: "8",
1330            width_tokens: quote! { px(8.) },
1331            doc_string_suffix: "8px",
1332        },
1333        BorderStyleSuffix {
1334            suffix: "9",
1335            width_tokens: quote! { px(9.) },
1336            doc_string_suffix: "9px",
1337        },
1338        BorderStyleSuffix {
1339            suffix: "10",
1340            width_tokens: quote! { px(10.) },
1341            doc_string_suffix: "10px",
1342        },
1343        BorderStyleSuffix {
1344            suffix: "11",
1345            width_tokens: quote! { px(11.) },
1346            doc_string_suffix: "11px",
1347        },
1348        BorderStyleSuffix {
1349            suffix: "12",
1350            width_tokens: quote! { px(12.) },
1351            doc_string_suffix: "12px",
1352        },
1353        BorderStyleSuffix {
1354            suffix: "16",
1355            width_tokens: quote! { px(16.) },
1356            doc_string_suffix: "16px",
1357        },
1358        BorderStyleSuffix {
1359            suffix: "20",
1360            width_tokens: quote! { px(20.) },
1361            doc_string_suffix: "20px",
1362        },
1363        BorderStyleSuffix {
1364            suffix: "24",
1365            width_tokens: quote! { px(24.) },
1366            doc_string_suffix: "24px",
1367        },
1368        BorderStyleSuffix {
1369            suffix: "32",
1370            width_tokens: quote! { px(32.) },
1371            doc_string_suffix: "32px",
1372        },
1373    ]
1374}