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 border_style_methods(input: TokenStream) -> TokenStream {
 321    let input = parse_macro_input!(input as StyleableMacroInput);
 322    let visibility = input.method_visibility;
 323
 324    let mut methods = Vec::new();
 325
 326    for border_style_prefix in border_prefixes() {
 327        methods.push(generate_custom_value_setter(
 328            visibility.clone(),
 329            border_style_prefix.prefix,
 330            quote! { AbsoluteLength },
 331            &border_style_prefix.fields,
 332            border_style_prefix.doc_string_prefix,
 333        ));
 334
 335        for border_style_suffix in border_suffixes() {
 336            methods.push(generate_predefined_setter(
 337                visibility.clone(),
 338                border_style_prefix.prefix,
 339                border_style_suffix.suffix,
 340                &border_style_prefix.fields,
 341                &border_style_suffix.width_tokens,
 342                false,
 343                &format!(
 344                    "{prefix}\n\n{suffix}",
 345                    prefix = border_style_prefix.doc_string_prefix,
 346                    suffix = border_style_suffix.doc_string_suffix,
 347                ),
 348            ));
 349        }
 350    }
 351
 352    let output = quote! {
 353        /// Sets the border color of the element.
 354        #visibility fn border_color<C>(mut self, border_color: C) -> Self
 355        where
 356            C: Into<gpui::Hsla>,
 357            Self: Sized,
 358        {
 359            self.style().border_color = Some(border_color.into());
 360            self
 361        }
 362
 363        #(#methods)*
 364    };
 365
 366    output.into()
 367}
 368
 369pub fn box_shadow_style_methods(input: TokenStream) -> TokenStream {
 370    let input = parse_macro_input!(input as StyleableMacroInput);
 371    let visibility = input.method_visibility;
 372    let output = quote! {
 373        /// Sets the box shadow of the element.
 374        /// [Docs](https://tailwindcss.com/docs/box-shadow)
 375        #visibility fn shadow(mut self, shadows: smallvec::SmallVec<[gpui::BoxShadow; 2]>) -> Self {
 376            self.style().box_shadow = Some(shadows);
 377            self
 378        }
 379
 380        /// Clears the box shadow of the element.
 381        /// [Docs](https://tailwindcss.com/docs/box-shadow)
 382        #visibility fn shadow_none(mut self) -> Self {
 383            self.style().box_shadow = Some(Default::default());
 384            self
 385        }
 386
 387        /// Sets the box shadow of the element.
 388        /// [Docs](https://tailwindcss.com/docs/box-shadow)
 389        #visibility fn shadow_sm(mut self) -> Self {
 390            use gpui::{BoxShadow, hsla, point, px};
 391            use smallvec::smallvec;
 392
 393            self.style().box_shadow = Some(smallvec![BoxShadow {
 394                color: hsla(0., 0., 0., 0.05),
 395                offset: point(px(0.), px(1.)),
 396                blur_radius: px(2.),
 397                spread_radius: px(0.),
 398            }]);
 399            self
 400        }
 401
 402        /// Sets the box shadow of the element.
 403        /// [Docs](https://tailwindcss.com/docs/box-shadow)
 404        #visibility fn shadow_md(mut self) -> Self {
 405            use gpui::{BoxShadow, hsla, point, px};
 406            use smallvec::smallvec;
 407
 408            self.style().box_shadow = Some(smallvec![
 409                BoxShadow {
 410                    color: hsla(0.5, 0., 0., 0.1),
 411                    offset: point(px(0.), px(4.)),
 412                    blur_radius: px(6.),
 413                    spread_radius: px(-1.),
 414                },
 415                BoxShadow {
 416                    color: hsla(0., 0., 0., 0.1),
 417                    offset: point(px(0.), px(2.)),
 418                    blur_radius: px(4.),
 419                    spread_radius: px(-2.),
 420                }
 421            ]);
 422            self
 423        }
 424
 425        /// Sets the box shadow of the element.
 426        /// [Docs](https://tailwindcss.com/docs/box-shadow)
 427        #visibility fn shadow_lg(mut self) -> Self {
 428            use gpui::{BoxShadow, hsla, point, px};
 429            use smallvec::smallvec;
 430
 431            self.style().box_shadow = Some(smallvec![
 432                BoxShadow {
 433                    color: hsla(0., 0., 0., 0.1),
 434                    offset: point(px(0.), px(10.)),
 435                    blur_radius: px(15.),
 436                    spread_radius: px(-3.),
 437                },
 438                BoxShadow {
 439                    color: hsla(0., 0., 0., 0.1),
 440                    offset: point(px(0.), px(4.)),
 441                    blur_radius: px(6.),
 442                    spread_radius: px(-4.),
 443                }
 444            ]);
 445            self
 446        }
 447
 448        /// Sets the box shadow of the element.
 449        /// [Docs](https://tailwindcss.com/docs/box-shadow)
 450        #visibility fn shadow_xl(mut self) -> Self {
 451            use gpui::{BoxShadow, hsla, point, px};
 452            use smallvec::smallvec;
 453
 454            self.style().box_shadow = Some(smallvec![
 455                BoxShadow {
 456                    color: hsla(0., 0., 0., 0.1),
 457                    offset: point(px(0.), px(20.)),
 458                    blur_radius: px(25.),
 459                    spread_radius: px(-5.),
 460                },
 461                BoxShadow {
 462                    color: hsla(0., 0., 0., 0.1),
 463                    offset: point(px(0.), px(8.)),
 464                    blur_radius: px(10.),
 465                    spread_radius: px(-6.),
 466                }
 467            ]);
 468            self
 469        }
 470
 471        /// Sets the box shadow of the element.
 472        /// [Docs](https://tailwindcss.com/docs/box-shadow)
 473        #visibility fn shadow_2xl(mut self) -> Self {
 474            use gpui::{BoxShadow, hsla, point, px};
 475            use smallvec::smallvec;
 476
 477            self.style().box_shadow = Some(smallvec![BoxShadow {
 478                color: hsla(0., 0., 0., 0.25),
 479                offset: point(px(0.), px(25.)),
 480                blur_radius: px(50.),
 481                spread_radius: px(-12.),
 482            }]);
 483            self
 484        }
 485    };
 486
 487    output.into()
 488}
 489
 490struct BoxStylePrefix {
 491    prefix: &'static str,
 492    auto_allowed: bool,
 493    fields: Vec<TokenStream2>,
 494    doc_string_prefix: &'static str,
 495}
 496
 497struct BoxStyleSuffix {
 498    suffix: &'static str,
 499    length_tokens: TokenStream2,
 500    doc_string_suffix: &'static str,
 501}
 502
 503struct CornerStylePrefix {
 504    prefix: &'static str,
 505    fields: Vec<TokenStream2>,
 506    doc_string_prefix: &'static str,
 507}
 508
 509struct CornerStyleSuffix {
 510    suffix: &'static str,
 511    radius_tokens: TokenStream2,
 512    doc_string_suffix: &'static str,
 513}
 514
 515struct BorderStylePrefix {
 516    prefix: &'static str,
 517    fields: Vec<TokenStream2>,
 518    doc_string_prefix: &'static str,
 519}
 520
 521struct BorderStyleSuffix {
 522    suffix: &'static str,
 523    width_tokens: TokenStream2,
 524    doc_string_suffix: &'static str,
 525}
 526
 527fn generate_box_style_methods(
 528    prefixes: Vec<BoxStylePrefix>,
 529    suffixes: Vec<BoxStyleSuffix>,
 530    visibility: Visibility,
 531) -> Vec<TokenStream2> {
 532    let mut methods = Vec::new();
 533
 534    for box_style_prefix in prefixes {
 535        methods.push(generate_custom_value_setter(
 536            visibility.clone(),
 537            box_style_prefix.prefix,
 538            if box_style_prefix.auto_allowed {
 539                quote! { Length }
 540            } else {
 541                quote! { DefiniteLength }
 542            },
 543            &box_style_prefix.fields,
 544            box_style_prefix.doc_string_prefix,
 545        ));
 546
 547        for box_style_suffix in &suffixes {
 548            if box_style_suffix.suffix != "auto" || box_style_prefix.auto_allowed {
 549                methods.push(generate_predefined_setter(
 550                    visibility.clone(),
 551                    box_style_prefix.prefix,
 552                    box_style_suffix.suffix,
 553                    &box_style_prefix.fields,
 554                    &box_style_suffix.length_tokens,
 555                    false,
 556                    &format!(
 557                        "{prefix}\n\n{suffix}",
 558                        prefix = box_style_prefix.doc_string_prefix,
 559                        suffix = box_style_suffix.doc_string_suffix,
 560                    ),
 561                ));
 562            }
 563
 564            if box_style_suffix.suffix != "auto" {
 565                methods.push(generate_predefined_setter(
 566                    visibility.clone(),
 567                    box_style_prefix.prefix,
 568                    box_style_suffix.suffix,
 569                    &box_style_prefix.fields,
 570                    &box_style_suffix.length_tokens,
 571                    true,
 572                    &format!(
 573                        "{prefix}\n\n{suffix}",
 574                        prefix = box_style_prefix.doc_string_prefix,
 575                        suffix = box_style_suffix.doc_string_suffix,
 576                    ),
 577                ));
 578            }
 579        }
 580    }
 581
 582    methods
 583}
 584
 585fn generate_methods() -> Vec<TokenStream2> {
 586    let visibility = Visibility::Inherited;
 587    let mut methods =
 588        generate_box_style_methods(box_prefixes(), box_style_suffixes(), visibility.clone());
 589
 590    for corner_style_prefix in corner_prefixes() {
 591        methods.push(generate_custom_value_setter(
 592            visibility.clone(),
 593            corner_style_prefix.prefix,
 594            quote! { AbsoluteLength },
 595            &corner_style_prefix.fields,
 596            corner_style_prefix.doc_string_prefix,
 597        ));
 598
 599        for corner_style_suffix in corner_suffixes() {
 600            methods.push(generate_predefined_setter(
 601                visibility.clone(),
 602                corner_style_prefix.prefix,
 603                corner_style_suffix.suffix,
 604                &corner_style_prefix.fields,
 605                &corner_style_suffix.radius_tokens,
 606                false,
 607                &format!(
 608                    "{prefix}\n\n{suffix}",
 609                    prefix = corner_style_prefix.doc_string_prefix,
 610                    suffix = corner_style_suffix.doc_string_suffix,
 611                ),
 612            ));
 613        }
 614    }
 615
 616    methods
 617}
 618
 619fn generate_predefined_setter(
 620    visibility: Visibility,
 621    name: &'static str,
 622    length: &'static str,
 623    fields: &[TokenStream2],
 624    length_tokens: &TokenStream2,
 625    negate: bool,
 626    doc_string: &str,
 627) -> TokenStream2 {
 628    let (negation_qualifier, negation_token) = if negate {
 629        ("_neg", quote! { - })
 630    } else {
 631        ("", quote! {})
 632    };
 633
 634    let method_name = if length.is_empty() {
 635        format_ident!("{name}{negation_qualifier}")
 636    } else {
 637        format_ident!("{name}{negation_qualifier}_{length}")
 638    };
 639
 640    let field_assignments = fields
 641        .iter()
 642        .map(|field_tokens| {
 643            quote! {
 644                style.#field_tokens = Some((#negation_token gpui::#length_tokens).into());
 645            }
 646        })
 647        .collect::<Vec<_>>();
 648
 649    let method = quote! {
 650        #[doc = #doc_string]
 651        #visibility fn #method_name(mut self) -> Self {
 652            let style = self.style();
 653            #(#field_assignments)*
 654            self
 655        }
 656    };
 657
 658    method
 659}
 660
 661fn generate_custom_value_setter(
 662    visibility: Visibility,
 663    prefix: &str,
 664    length_type: TokenStream2,
 665    fields: &[TokenStream2],
 666    doc_string: &str,
 667) -> TokenStream2 {
 668    let method_name = format_ident!("{}", prefix);
 669
 670    let mut iter = fields.iter();
 671    let last = iter.next_back().unwrap();
 672    let field_assignments = iter
 673        .map(|field_tokens| {
 674            quote! {
 675                style.#field_tokens = Some(length.clone().into());
 676            }
 677        })
 678        .chain(std::iter::once(quote! {
 679            style.#last = Some(length.into());
 680        }))
 681        .collect::<Vec<_>>();
 682
 683    let method = quote! {
 684        #[doc = #doc_string]
 685        #visibility fn #method_name(mut self, length: impl std::clone::Clone + Into<gpui::#length_type>) -> Self {
 686            let style = self.style();
 687            #(#field_assignments)*
 688            self
 689        }
 690    };
 691
 692    method
 693}
 694
 695fn margin_box_style_prefixes() -> Vec<BoxStylePrefix> {
 696    vec![
 697        BoxStylePrefix {
 698            prefix: "m",
 699            auto_allowed: true,
 700            fields: vec![
 701                quote! { margin.top },
 702                quote! { margin.bottom },
 703                quote! { margin.left },
 704                quote! { margin.right },
 705            ],
 706            doc_string_prefix: "Sets the margin of the element. [Docs](https://tailwindcss.com/docs/margin)",
 707        },
 708        BoxStylePrefix {
 709            prefix: "mt",
 710            auto_allowed: true,
 711            fields: vec![quote! { margin.top }],
 712            doc_string_prefix: "Sets the top margin of the element. [Docs](https://tailwindcss.com/docs/margin#add-margin-to-a-single-side)",
 713        },
 714        BoxStylePrefix {
 715            prefix: "mb",
 716            auto_allowed: true,
 717            fields: vec![quote! { margin.bottom }],
 718            doc_string_prefix: "Sets the bottom margin of the element. [Docs](https://tailwindcss.com/docs/margin#add-margin-to-a-single-side)",
 719        },
 720        BoxStylePrefix {
 721            prefix: "my",
 722            auto_allowed: true,
 723            fields: vec![quote! { margin.top }, quote! { margin.bottom }],
 724            doc_string_prefix: "Sets the vertical margin of the element. [Docs](https://tailwindcss.com/docs/margin#add-vertical-margin)",
 725        },
 726        BoxStylePrefix {
 727            prefix: "mx",
 728            auto_allowed: true,
 729            fields: vec![quote! { margin.left }, quote! { margin.right }],
 730            doc_string_prefix: "Sets the horizontal margin of the element. [Docs](https://tailwindcss.com/docs/margin#add-horizontal-margin)",
 731        },
 732        BoxStylePrefix {
 733            prefix: "ml",
 734            auto_allowed: true,
 735            fields: vec![quote! { margin.left }],
 736            doc_string_prefix: "Sets the left margin of the element. [Docs](https://tailwindcss.com/docs/margin#add-margin-to-a-single-side)",
 737        },
 738        BoxStylePrefix {
 739            prefix: "mr",
 740            auto_allowed: true,
 741            fields: vec![quote! { margin.right }],
 742            doc_string_prefix: "Sets the right margin of the element. [Docs](https://tailwindcss.com/docs/margin#add-margin-to-a-single-side)",
 743        },
 744    ]
 745}
 746
 747fn padding_box_style_prefixes() -> Vec<BoxStylePrefix> {
 748    vec![
 749        BoxStylePrefix {
 750            prefix: "p",
 751            auto_allowed: false,
 752            fields: vec![
 753                quote! { padding.top },
 754                quote! { padding.bottom },
 755                quote! { padding.left },
 756                quote! { padding.right },
 757            ],
 758            doc_string_prefix: "Sets the padding of the element. [Docs](https://tailwindcss.com/docs/padding)",
 759        },
 760        BoxStylePrefix {
 761            prefix: "pt",
 762            auto_allowed: false,
 763            fields: vec![quote! { padding.top }],
 764            doc_string_prefix: "Sets the top padding of the element. [Docs](https://tailwindcss.com/docs/padding#add-padding-to-a-single-side)",
 765        },
 766        BoxStylePrefix {
 767            prefix: "pb",
 768            auto_allowed: false,
 769            fields: vec![quote! { padding.bottom }],
 770            doc_string_prefix: "Sets the bottom padding of the element. [Docs](https://tailwindcss.com/docs/padding#add-padding-to-a-single-side)",
 771        },
 772        BoxStylePrefix {
 773            prefix: "px",
 774            auto_allowed: false,
 775            fields: vec![quote! { padding.left }, quote! { padding.right }],
 776            doc_string_prefix: "Sets the horizontal padding of the element. [Docs](https://tailwindcss.com/docs/padding#add-horizontal-padding)",
 777        },
 778        BoxStylePrefix {
 779            prefix: "py",
 780            auto_allowed: false,
 781            fields: vec![quote! { padding.top }, quote! { padding.bottom }],
 782            doc_string_prefix: "Sets the vertical padding of the element. [Docs](https://tailwindcss.com/docs/padding#add-vertical-padding)",
 783        },
 784        BoxStylePrefix {
 785            prefix: "pl",
 786            auto_allowed: false,
 787            fields: vec![quote! { padding.left }],
 788            doc_string_prefix: "Sets the left padding of the element. [Docs](https://tailwindcss.com/docs/padding#add-padding-to-a-single-side)",
 789        },
 790        BoxStylePrefix {
 791            prefix: "pr",
 792            auto_allowed: false,
 793            fields: vec![quote! { padding.right }],
 794            doc_string_prefix: "Sets the right padding of the element. [Docs](https://tailwindcss.com/docs/padding#add-padding-to-a-single-side)",
 795        },
 796    ]
 797}
 798
 799fn position_box_style_prefixes() -> Vec<BoxStylePrefix> {
 800    vec![
 801        BoxStylePrefix {
 802            prefix: "inset",
 803            auto_allowed: true,
 804            fields: vec![
 805                quote! { inset.top },
 806                quote! { inset.right },
 807                quote! { inset.bottom },
 808                quote! { inset.left },
 809            ],
 810            doc_string_prefix: "Sets the top, right, bottom, and left values of a positioned element. [Docs](https://tailwindcss.com/docs/top-right-bottom-left)",
 811        },
 812        BoxStylePrefix {
 813            prefix: "top",
 814            auto_allowed: true,
 815            fields: vec![quote! { inset.top }],
 816            doc_string_prefix: "Sets the top value of a positioned element. [Docs](https://tailwindcss.com/docs/top-right-bottom-left)",
 817        },
 818        BoxStylePrefix {
 819            prefix: "bottom",
 820            auto_allowed: true,
 821            fields: vec![quote! { inset.bottom }],
 822            doc_string_prefix: "Sets the bottom value of a positioned element. [Docs](https://tailwindcss.com/docs/top-right-bottom-left)",
 823        },
 824        BoxStylePrefix {
 825            prefix: "left",
 826            auto_allowed: true,
 827            fields: vec![quote! { inset.left }],
 828            doc_string_prefix: "Sets the left value of a positioned element. [Docs](https://tailwindcss.com/docs/top-right-bottom-left)",
 829        },
 830        BoxStylePrefix {
 831            prefix: "right",
 832            auto_allowed: true,
 833            fields: vec![quote! { inset.right }],
 834            doc_string_prefix: "Sets the right value of a positioned element. [Docs](https://tailwindcss.com/docs/top-right-bottom-left)",
 835        },
 836    ]
 837}
 838
 839fn box_prefixes() -> Vec<BoxStylePrefix> {
 840    vec![
 841        BoxStylePrefix {
 842            prefix: "w",
 843            auto_allowed: true,
 844            fields: vec![quote! { size.width }],
 845            doc_string_prefix: "Sets the width of the element. [Docs](https://tailwindcss.com/docs/width)",
 846        },
 847        BoxStylePrefix {
 848            prefix: "h",
 849            auto_allowed: true,
 850            fields: vec![quote! { size.height }],
 851            doc_string_prefix: "Sets the height of the element. [Docs](https://tailwindcss.com/docs/height)",
 852        },
 853        BoxStylePrefix {
 854            prefix: "size",
 855            auto_allowed: true,
 856            fields: vec![quote! {size.width}, quote! {size.height}],
 857            doc_string_prefix: "Sets the width and height of the element.",
 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: "min_w",
 863            auto_allowed: true,
 864            fields: vec![quote! { min_size.width }],
 865            doc_string_prefix: "Sets the minimum width of the element. [Docs](https://tailwindcss.com/docs/min-width)",
 866        },
 867        // TODO: These don't use the same size ramp as the others
 868        // see https://tailwindcss.com/docs/max-width
 869        BoxStylePrefix {
 870            prefix: "min_h",
 871            auto_allowed: true,
 872            fields: vec![quote! { min_size.height }],
 873            doc_string_prefix: "Sets the minimum height of the element. [Docs](https://tailwindcss.com/docs/min-height)",
 874        },
 875        // TODO: These don't use the same size ramp as the others
 876        // see https://tailwindcss.com/docs/max-width
 877        BoxStylePrefix {
 878            prefix: "max_w",
 879            auto_allowed: true,
 880            fields: vec![quote! { max_size.width }],
 881            doc_string_prefix: "Sets the maximum width of the element. [Docs](https://tailwindcss.com/docs/max-width)",
 882        },
 883        // TODO: These don't use the same size ramp as the others
 884        // see https://tailwindcss.com/docs/max-width
 885        BoxStylePrefix {
 886            prefix: "max_h",
 887            auto_allowed: true,
 888            fields: vec![quote! { max_size.height }],
 889            doc_string_prefix: "Sets the maximum height of the element. [Docs](https://tailwindcss.com/docs/max-height)",
 890        },
 891        BoxStylePrefix {
 892            prefix: "gap",
 893            auto_allowed: false,
 894            fields: vec![quote! { gap.width }, quote! { gap.height }],
 895            doc_string_prefix: "Sets the gap between rows and columns in flex layouts. [Docs](https://tailwindcss.com/docs/gap)",
 896        },
 897        BoxStylePrefix {
 898            prefix: "gap_x",
 899            auto_allowed: false,
 900            fields: vec![quote! { gap.width }],
 901            doc_string_prefix: "Sets the gap between columns in flex layouts. [Docs](https://tailwindcss.com/docs/gap#changing-row-and-column-gaps-independently)",
 902        },
 903        BoxStylePrefix {
 904            prefix: "gap_y",
 905            auto_allowed: false,
 906            fields: vec![quote! { gap.height }],
 907            doc_string_prefix: "Sets the gap between rows in flex layouts. [Docs](https://tailwindcss.com/docs/gap#changing-row-and-column-gaps-independently)",
 908        },
 909    ]
 910}
 911
 912fn box_style_suffixes() -> Vec<BoxStyleSuffix> {
 913    vec![
 914        BoxStyleSuffix {
 915            suffix: "0",
 916            length_tokens: quote! { px(0.) },
 917            doc_string_suffix: "0px",
 918        },
 919        BoxStyleSuffix {
 920            suffix: "0p5",
 921            length_tokens: quote! { rems(0.125) },
 922            doc_string_suffix: "2px (0.125rem)",
 923        },
 924        BoxStyleSuffix {
 925            suffix: "1",
 926            length_tokens: quote! { rems(0.25) },
 927            doc_string_suffix: "4px (0.25rem)",
 928        },
 929        BoxStyleSuffix {
 930            suffix: "1p5",
 931            length_tokens: quote! { rems(0.375) },
 932            doc_string_suffix: "6px (0.375rem)",
 933        },
 934        BoxStyleSuffix {
 935            suffix: "2",
 936            length_tokens: quote! { rems(0.5) },
 937            doc_string_suffix: "8px (0.5rem)",
 938        },
 939        BoxStyleSuffix {
 940            suffix: "2p5",
 941            length_tokens: quote! { rems(0.625) },
 942            doc_string_suffix: "10px (0.625rem)",
 943        },
 944        BoxStyleSuffix {
 945            suffix: "3",
 946            length_tokens: quote! { rems(0.75) },
 947            doc_string_suffix: "12px (0.75rem)",
 948        },
 949        BoxStyleSuffix {
 950            suffix: "3p5",
 951            length_tokens: quote! { rems(0.875) },
 952            doc_string_suffix: "14px (0.875rem)",
 953        },
 954        BoxStyleSuffix {
 955            suffix: "4",
 956            length_tokens: quote! { rems(1.) },
 957            doc_string_suffix: "16px (1rem)",
 958        },
 959        BoxStyleSuffix {
 960            suffix: "5",
 961            length_tokens: quote! { rems(1.25) },
 962            doc_string_suffix: "20px (1.25rem)",
 963        },
 964        BoxStyleSuffix {
 965            suffix: "6",
 966            length_tokens: quote! { rems(1.5) },
 967            doc_string_suffix: "24px (1.5rem)",
 968        },
 969        BoxStyleSuffix {
 970            suffix: "7",
 971            length_tokens: quote! { rems(1.75) },
 972            doc_string_suffix: "28px (1.75rem)",
 973        },
 974        BoxStyleSuffix {
 975            suffix: "8",
 976            length_tokens: quote! { rems(2.0) },
 977            doc_string_suffix: "32px (2rem)",
 978        },
 979        BoxStyleSuffix {
 980            suffix: "9",
 981            length_tokens: quote! { rems(2.25) },
 982            doc_string_suffix: "36px (2.25rem)",
 983        },
 984        BoxStyleSuffix {
 985            suffix: "10",
 986            length_tokens: quote! { rems(2.5) },
 987            doc_string_suffix: "40px (2.5rem)",
 988        },
 989        BoxStyleSuffix {
 990            suffix: "11",
 991            length_tokens: quote! { rems(2.75) },
 992            doc_string_suffix: "44px (2.75rem)",
 993        },
 994        BoxStyleSuffix {
 995            suffix: "12",
 996            length_tokens: quote! { rems(3.) },
 997            doc_string_suffix: "48px (3rem)",
 998        },
 999        BoxStyleSuffix {
1000            suffix: "16",
1001            length_tokens: quote! { rems(4.) },
1002            doc_string_suffix: "64px (4rem)",
1003        },
1004        BoxStyleSuffix {
1005            suffix: "20",
1006            length_tokens: quote! { rems(5.) },
1007            doc_string_suffix: "80px (5rem)",
1008        },
1009        BoxStyleSuffix {
1010            suffix: "24",
1011            length_tokens: quote! { rems(6.) },
1012            doc_string_suffix: "96px (6rem)",
1013        },
1014        BoxStyleSuffix {
1015            suffix: "32",
1016            length_tokens: quote! { rems(8.) },
1017            doc_string_suffix: "128px (8rem)",
1018        },
1019        BoxStyleSuffix {
1020            suffix: "40",
1021            length_tokens: quote! { rems(10.) },
1022            doc_string_suffix: "160px (10rem)",
1023        },
1024        BoxStyleSuffix {
1025            suffix: "48",
1026            length_tokens: quote! { rems(12.) },
1027            doc_string_suffix: "192px (12rem)",
1028        },
1029        BoxStyleSuffix {
1030            suffix: "56",
1031            length_tokens: quote! { rems(14.) },
1032            doc_string_suffix: "224px (14rem)",
1033        },
1034        BoxStyleSuffix {
1035            suffix: "64",
1036            length_tokens: quote! { rems(16.) },
1037            doc_string_suffix: "256px (16rem)",
1038        },
1039        BoxStyleSuffix {
1040            suffix: "72",
1041            length_tokens: quote! { rems(18.) },
1042            doc_string_suffix: "288px (18rem)",
1043        },
1044        BoxStyleSuffix {
1045            suffix: "80",
1046            length_tokens: quote! { rems(20.) },
1047            doc_string_suffix: "320px (20rem)",
1048        },
1049        BoxStyleSuffix {
1050            suffix: "96",
1051            length_tokens: quote! { rems(24.) },
1052            doc_string_suffix: "384px (24rem)",
1053        },
1054        BoxStyleSuffix {
1055            suffix: "112",
1056            length_tokens: quote! { rems(28.) },
1057            doc_string_suffix: "448px (28rem)",
1058        },
1059        BoxStyleSuffix {
1060            suffix: "128",
1061            length_tokens: quote! { rems(32.) },
1062            doc_string_suffix: "512px (32rem)",
1063        },
1064        BoxStyleSuffix {
1065            suffix: "auto",
1066            length_tokens: quote! { auto() },
1067            doc_string_suffix: "Auto",
1068        },
1069        BoxStyleSuffix {
1070            suffix: "px",
1071            length_tokens: quote! { px(1.) },
1072            doc_string_suffix: "1px",
1073        },
1074        BoxStyleSuffix {
1075            suffix: "full",
1076            length_tokens: quote! { relative(1.) },
1077            doc_string_suffix: "100%",
1078        },
1079        BoxStyleSuffix {
1080            suffix: "1_2",
1081            length_tokens: quote! { relative(0.5) },
1082            doc_string_suffix: "50% (1/2)",
1083        },
1084        BoxStyleSuffix {
1085            suffix: "1_3",
1086            length_tokens: quote! { relative(1./3.) },
1087            doc_string_suffix: "33% (1/3)",
1088        },
1089        BoxStyleSuffix {
1090            suffix: "2_3",
1091            length_tokens: quote! { relative(2./3.) },
1092            doc_string_suffix: "66% (2/3)",
1093        },
1094        BoxStyleSuffix {
1095            suffix: "1_4",
1096            length_tokens: quote! { relative(0.25) },
1097            doc_string_suffix: "25% (1/4)",
1098        },
1099        BoxStyleSuffix {
1100            suffix: "2_4",
1101            length_tokens: quote! { relative(0.5) },
1102            doc_string_suffix: "50% (2/4)",
1103        },
1104        BoxStyleSuffix {
1105            suffix: "3_4",
1106            length_tokens: quote! { relative(0.75) },
1107            doc_string_suffix: "75% (3/4)",
1108        },
1109        BoxStyleSuffix {
1110            suffix: "1_5",
1111            length_tokens: quote! { relative(0.2) },
1112            doc_string_suffix: "20% (1/5)",
1113        },
1114        BoxStyleSuffix {
1115            suffix: "2_5",
1116            length_tokens: quote! { relative(0.4) },
1117            doc_string_suffix: "40% (2/5)",
1118        },
1119        BoxStyleSuffix {
1120            suffix: "3_5",
1121            length_tokens: quote! { relative(0.6) },
1122            doc_string_suffix: "60% (3/5)",
1123        },
1124        BoxStyleSuffix {
1125            suffix: "4_5",
1126            length_tokens: quote! { relative(0.8) },
1127            doc_string_suffix: "80% (4/5)",
1128        },
1129        BoxStyleSuffix {
1130            suffix: "1_6",
1131            length_tokens: quote! { relative(1./6.) },
1132            doc_string_suffix: "16% (1/6)",
1133        },
1134        BoxStyleSuffix {
1135            suffix: "5_6",
1136            length_tokens: quote! { relative(5./6.) },
1137            doc_string_suffix: "80% (5/6)",
1138        },
1139        BoxStyleSuffix {
1140            suffix: "1_12",
1141            length_tokens: quote! { relative(1./12.) },
1142            doc_string_suffix: "8% (1/12)",
1143        },
1144    ]
1145}
1146
1147fn corner_prefixes() -> Vec<CornerStylePrefix> {
1148    vec![
1149        CornerStylePrefix {
1150            prefix: "rounded",
1151            fields: vec![
1152                quote! { corner_radii.top_left },
1153                quote! { corner_radii.top_right },
1154                quote! { corner_radii.bottom_right },
1155                quote! { corner_radii.bottom_left },
1156            ],
1157            doc_string_prefix: "Sets the border radius of the element. [Docs](https://tailwindcss.com/docs/border-radius)",
1158        },
1159        CornerStylePrefix {
1160            prefix: "rounded_t",
1161            fields: vec![
1162                quote! { corner_radii.top_left },
1163                quote! { corner_radii.top_right },
1164            ],
1165            doc_string_prefix: "Sets the border radius of the top side of the element. [Docs](https://tailwindcss.com/docs/border-radius#rounding-sides-separately)",
1166        },
1167        CornerStylePrefix {
1168            prefix: "rounded_b",
1169            fields: vec![
1170                quote! { corner_radii.bottom_left },
1171                quote! { corner_radii.bottom_right },
1172            ],
1173            doc_string_prefix: "Sets the border radius of the bottom side of the element. [Docs](https://tailwindcss.com/docs/border-radius#rounding-sides-separately)",
1174        },
1175        CornerStylePrefix {
1176            prefix: "rounded_r",
1177            fields: vec![
1178                quote! { corner_radii.top_right },
1179                quote! { corner_radii.bottom_right },
1180            ],
1181            doc_string_prefix: "Sets the border radius of the right side of the element. [Docs](https://tailwindcss.com/docs/border-radius#rounding-sides-separately)",
1182        },
1183        CornerStylePrefix {
1184            prefix: "rounded_l",
1185            fields: vec![
1186                quote! { corner_radii.top_left },
1187                quote! { corner_radii.bottom_left },
1188            ],
1189            doc_string_prefix: "Sets the border radius of the left side of the element. [Docs](https://tailwindcss.com/docs/border-radius#rounding-sides-separately)",
1190        },
1191        CornerStylePrefix {
1192            prefix: "rounded_tl",
1193            fields: vec![quote! { corner_radii.top_left }],
1194            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)",
1195        },
1196        CornerStylePrefix {
1197            prefix: "rounded_tr",
1198            fields: vec![quote! { corner_radii.top_right }],
1199            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)",
1200        },
1201        CornerStylePrefix {
1202            prefix: "rounded_bl",
1203            fields: vec![quote! { corner_radii.bottom_left }],
1204            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)",
1205        },
1206        CornerStylePrefix {
1207            prefix: "rounded_br",
1208            fields: vec![quote! { corner_radii.bottom_right }],
1209            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)",
1210        },
1211    ]
1212}
1213
1214fn corner_suffixes() -> Vec<CornerStyleSuffix> {
1215    vec![
1216        CornerStyleSuffix {
1217            suffix: "none",
1218            radius_tokens: quote! { px(0.) },
1219            doc_string_suffix: "0px",
1220        },
1221        CornerStyleSuffix {
1222            suffix: "sm",
1223            radius_tokens: quote! { rems(0.125) },
1224            doc_string_suffix: "2px (0.125rem)",
1225        },
1226        CornerStyleSuffix {
1227            suffix: "md",
1228            radius_tokens: quote! { rems(0.25) },
1229            doc_string_suffix: "4px (0.25rem)",
1230        },
1231        CornerStyleSuffix {
1232            suffix: "lg",
1233            radius_tokens: quote! { rems(0.5) },
1234            doc_string_suffix: "8px (0.5rem)",
1235        },
1236        CornerStyleSuffix {
1237            suffix: "xl",
1238            radius_tokens: quote! { rems(0.75) },
1239            doc_string_suffix: "12px (0.75rem)",
1240        },
1241        CornerStyleSuffix {
1242            suffix: "2xl",
1243            radius_tokens: quote! { rems(1.) },
1244            doc_string_suffix: "16px (1rem)",
1245        },
1246        CornerStyleSuffix {
1247            suffix: "3xl",
1248            radius_tokens: quote! { rems(1.5) },
1249            doc_string_suffix: "24px (1.5rem)",
1250        },
1251        CornerStyleSuffix {
1252            suffix: "full",
1253            radius_tokens: quote! {  px(9999.) },
1254            doc_string_suffix: "9999px",
1255        },
1256    ]
1257}
1258
1259fn border_prefixes() -> Vec<BorderStylePrefix> {
1260    vec![
1261        BorderStylePrefix {
1262            prefix: "border",
1263            fields: vec![
1264                quote! { border_widths.top },
1265                quote! { border_widths.right },
1266                quote! { border_widths.bottom },
1267                quote! { border_widths.left },
1268            ],
1269            doc_string_prefix: "Sets the border width of the element. [Docs](https://tailwindcss.com/docs/border-width)"
1270        },
1271        BorderStylePrefix {
1272            prefix: "border_t",
1273            fields: vec![quote! { border_widths.top }],
1274            doc_string_prefix: "Sets the border width of the top side of the element. [Docs](https://tailwindcss.com/docs/border-width#individual-sides)"
1275        },
1276        BorderStylePrefix {
1277            prefix: "border_b",
1278            fields: vec![quote! { border_widths.bottom }],
1279            doc_string_prefix: "Sets the border width of the bottom side of the element. [Docs](https://tailwindcss.com/docs/border-width#individual-sides)"
1280        },
1281        BorderStylePrefix {
1282            prefix: "border_r",
1283            fields: vec![quote! { border_widths.right }],
1284            doc_string_prefix: "Sets the border width of the right side of the element. [Docs](https://tailwindcss.com/docs/border-width#individual-sides)"
1285        },
1286        BorderStylePrefix {
1287            prefix: "border_l",
1288            fields: vec![quote! { border_widths.left }],
1289            doc_string_prefix: "Sets the border width of the left side of the element. [Docs](https://tailwindcss.com/docs/border-width#individual-sides)"
1290        },
1291        BorderStylePrefix {
1292            prefix: "border_x",
1293            fields: vec![
1294                quote! { border_widths.left },
1295                quote! { border_widths.right },
1296            ],
1297            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)"
1298        },
1299        BorderStylePrefix {
1300            prefix: "border_y",
1301            fields: vec![
1302                quote! { border_widths.top },
1303                quote! { border_widths.bottom },
1304            ],
1305            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)"
1306        },
1307    ]
1308}
1309
1310fn border_suffixes() -> Vec<BorderStyleSuffix> {
1311    vec![
1312        BorderStyleSuffix {
1313            suffix: "0",
1314            width_tokens: quote! { px(0.)},
1315            doc_string_suffix: "0px",
1316        },
1317        BorderStyleSuffix {
1318            suffix: "1",
1319            width_tokens: quote! { px(1.) },
1320            doc_string_suffix: "1px",
1321        },
1322        BorderStyleSuffix {
1323            suffix: "2",
1324            width_tokens: quote! { px(2.) },
1325            doc_string_suffix: "2px",
1326        },
1327        BorderStyleSuffix {
1328            suffix: "3",
1329            width_tokens: quote! { px(3.) },
1330            doc_string_suffix: "3px",
1331        },
1332        BorderStyleSuffix {
1333            suffix: "4",
1334            width_tokens: quote! { px(4.) },
1335            doc_string_suffix: "4px",
1336        },
1337        BorderStyleSuffix {
1338            suffix: "5",
1339            width_tokens: quote! { px(5.) },
1340            doc_string_suffix: "5px",
1341        },
1342        BorderStyleSuffix {
1343            suffix: "6",
1344            width_tokens: quote! { px(6.) },
1345            doc_string_suffix: "6px",
1346        },
1347        BorderStyleSuffix {
1348            suffix: "7",
1349            width_tokens: quote! { px(7.) },
1350            doc_string_suffix: "7px",
1351        },
1352        BorderStyleSuffix {
1353            suffix: "8",
1354            width_tokens: quote! { px(8.) },
1355            doc_string_suffix: "8px",
1356        },
1357        BorderStyleSuffix {
1358            suffix: "9",
1359            width_tokens: quote! { px(9.) },
1360            doc_string_suffix: "9px",
1361        },
1362        BorderStyleSuffix {
1363            suffix: "10",
1364            width_tokens: quote! { px(10.) },
1365            doc_string_suffix: "10px",
1366        },
1367        BorderStyleSuffix {
1368            suffix: "11",
1369            width_tokens: quote! { px(11.) },
1370            doc_string_suffix: "11px",
1371        },
1372        BorderStyleSuffix {
1373            suffix: "12",
1374            width_tokens: quote! { px(12.) },
1375            doc_string_suffix: "12px",
1376        },
1377        BorderStyleSuffix {
1378            suffix: "16",
1379            width_tokens: quote! { px(16.) },
1380            doc_string_suffix: "16px",
1381        },
1382        BorderStyleSuffix {
1383            suffix: "20",
1384            width_tokens: quote! { px(20.) },
1385            doc_string_suffix: "20px",
1386        },
1387        BorderStyleSuffix {
1388            suffix: "24",
1389            width_tokens: quote! { px(24.) },
1390            doc_string_suffix: "24px",
1391        },
1392        BorderStyleSuffix {
1393            suffix: "32",
1394            width_tokens: quote! { px(32.) },
1395            doc_string_suffix: "32px",
1396        },
1397    ]
1398}