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