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