styles.rs

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