styles.rs

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