Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Styling and Stylekit documentation is unintuitive #1095

Closed
FlorianJacta opened this issue Aug 27, 2024 · 7 comments
Closed

Styling and Stylekit documentation is unintuitive #1095

FlorianJacta opened this issue Aug 27, 2024 · 7 comments
Assignees
Labels
💬 Discussion Open for discussion and feedback 📄 Documentation Internal or public documentation 🖰 GUI Related to GUI 📈 Improvement Improvement of a feature. 🟥 Priority: Critical Must be fixed ASAP

Comments

@FlorianJacta
Copy link
Member

Description
Styling and Stylekit documentation is unintuitive. Users have reported that this sections could be greatly imroved.

  • How do you style your whole application?
  • How do you style visual elements?
  • How do you customize the Stylekit?
  • Where is the class referenced in the Stylekit? And how to use them?
  • How do I change the color of a text?

Everything was very confusing for users. We should have more example, a better explanation to enable them to achieve what they want.

@FlorianJacta FlorianJacta added 📈 Improvement Improvement of a feature. 📄 Documentation Internal or public documentation 🟧 Priority: High Stalls work on the project or its dependents labels Aug 27, 2024
@FlorianJacta
Copy link
Member Author

FlorianJacta commented Aug 28, 2024

We're receiving increasing complaints from users about the documentation. They’re struggling to perform even the most basic UI changes, as they’ve mentioned.

It's clear that the documentation needs improvement, particularly in guiding users through the process of modifying visual elements.

For instance, a common question has been, 'How do I make an input field longer?' This indicates that the current instructions are too unclear for users.

Restructuring the doc could help #1085

@FlorianJacta
Copy link
Member Author

We should put the Styling doc just below User Interface:

  • A sub-section should present how to style an application,
  • A sub-section should present how to style controls (putting text in red, adding margin, padding, and more).

This should refer to a Stylekit page that shows every class of the Stylekit.

@jrobinAV jrobinAV added 🟥 Priority: Critical Must be fixed ASAP and removed 🟧 Priority: High Stalls work on the project or its dependents labels Aug 30, 2024
@FlorianJacta
Copy link
Member Author

@FredLL-Avaiga answered another question on Styling to tell a user how to not capitalize the navbar:

.taipy-navbar .MuiButtonBase-root {
  text-transform: unset;
}

@FabienLelaquais @jrobinAV What do you think about having in each visual element page to add in the styling sections the relevant CSS selectors:

For example, navbar:

.taipy-navbar .MuiButtonBase-root {
  text-transform: unset;
}

/*add more*/

Selector:

.taipy-selector{
    margin:0px !important;
}

/* inside of selector */
.taipy-selector .MuiInputBase-root{
    background-color: #572c5f38;
    color: #221025;
    border-radius: 0px;
    height: 50px;
}

/* label of selector */
.taipy-selector .MuiFormLabel-root{
    color: #572c5f;
}

Input:

/* inside of input */
.taipy-input .MuiInputBase-root{
    background-color: #572c5f38;
    color: #221025;
    border-radius: 0px;
    height: 50px;
}

/* label of input */
.taipy-input .MuiFormLabel-root{
    color: #ce0707;
}

Table:

/* Table Head (apply to every child) */
.taipy-table .MuiTableHead-root .MuiTableRow-root>* {
    background-color: #b49cb9;
    color: #221025 !important;
    width: max-content;
}

/* Table Body - rows (apply to every child) */
.taipy-table .MuiTable-root {
    background-color: #572c5f0b;
    color: #221025;
}

/* Table Pagination/Footer  */
.taipy-table .MuiTablePagination-root{
    background-color: #572c5f38 !important;
    color: #221025 !important;
}

My opinion is that it could help a lot, but I am afraid this will require a lot of maintenance.

@jrobinAV jrobinAV added the 💬 Discussion Open for discussion and feedback label Sep 6, 2024
@FlorianJacta
Copy link
Member Author

Created issue to encapsulate the comment above: #1113

@FlorianJacta
Copy link
Member Author

FlorianJacta commented Dec 5, 2024

Would a Stylekit object be useful that provide ways to:

  • see what is inside the stylekit
  • set variables within the Stylekit
  • set the theme of your application from a set of predefined theme (that you could change)

POC:

main.py

from taipy.gui import Gui, notify
import taipy.gui.builder as tgb
from stylekit import stylekit as sk
import pandas as pd
from math import exp, cos

data = pd.DataFrame(
    {
        "Name": ["Florian", "John", "Jane", "Alice", "Bob"],
        "Value": [6, 7, 8, 9, 10],
    }
)
value = 10


def notify_user(state):
    notify(state, "info", "Date is clicked!")


def compute(value):
    return [cos(i / 6) * exp(-i * value / 600) for i in range(100)]


with tgb.Page() as page:
    tgb.text(
        "Hello World from Taipy",
        class_name=sk.typography.h1
        + sk.text_alignment.underline
        + sk.text_alignment.uppercase,
    )
    tgb.text(
        "This is a caption of my chart: we are seeing a sine wave",
        class_name=sk.typography.text_caption,
    )

    with tgb.layout(columns="1 1", class_name=sk.layout.align_columns_center):
        with tgb.part(sk.components.sidebar):
            tgb.chart(lambda value: compute(value))
        with tgb.part(sk.opacity.half_transparent):
            tgb.text("Change the data", class_name=sk.typography.h2)
            with tgb.layout("1 1"):
                tgb.date("2021-01-01", on_change=notify_user, class_name=sk.paddings.p4)
                tgb.selector(
                    "Florian",
                    lov=["Florian", "John", "Jane", "Alice", "Bob"],
                    on_change=notify_user,
                    class_name=sk.paddings.p4,
                    dropdown=True,
                )

            tgb.table("{data}")


sk.set_theme(sk.themes.Coffee)
# sk.set_primary_color("red")
# sk.set_secondary_color("red")
# sk.set_border_radius("10px")
# sk.set_font_family("Arial")
# sk.set_color_background_light("black")
# sk.set_color_background_dark("black")
# sk.set_color_paper_light("grey")
# sk.set_color_paper_dark("white")
# sk.set_input_button_height("40px")

Gui(page).run(stylekit=sk.get_stylekit())

Coffee
image

Industrial
image

Monospace
image

stylekit.py

# stylekit.py


class Components:
    card = "card "
    sidebar = "sidebar "
    # Add other components as needed


class Typography:
    h1 = "h1 "
    h2 = "h2 "
    h3 = "h3 "
    h4 = "h4 "
    h5 = "h5 "
    h6 = "h6 "
    text_body = "text-body "
    text_small = "text-small "
    text_caption = "text-caption "
    # Add other typography styles as needed


class TextWeights:
    weight300 = "text-weight300 "
    weight400 = "text-weight400 "
    weight500 = "text-weight500 "
    weight600 = "text-weight600 "
    weight700 = "text-weight700 "
    weight800 = "text-weight800 "
    weight900 = "text-weight900 "
    # Add other text weights as needed


class TextAlignment:
    left = "text-left "
    center = "text-center "
    right = "text-right "
    uppercase = "text-uppercase "
    no_transform = "text-no-transform "
    underline = "text-underline "
    no_underline = "text-no-underline "
    # Add other text alignments as needed


class Margins:
    """Margins ..."""

    m0 = "m0 "
    m_auto = "m-auto "
    m_half = "m-half "
    m1 = "m1 "
    m2 = "m2 "
    m3 = "m3 "
    m4 = "m4 "
    m5 = "m5 "
    m6 = "m6 "
    mt0 = "mt0 "
    mt_auto = "mt-auto "
    mt_half = "mt-half "
    mt1 = "mt1 "
    mt2 = "mt2 "
    mt3 = "mt3 "
    mt4 = "mt4 "
    mt5 = "mt5 "
    mt6 = "mt6 "
    mb0 = "mb0 "
    mb_auto = "mb-auto "
    mb_half = "mb-half "
    mb1 = "mb1 "
    mb2 = "mb2 "
    mb3 = "mb3 "
    mb4 = "mb4 "
    mb5 = "mb5 "
    mb6 = "mb6 "
    ml0 = "ml0 "
    ml_auto = "ml-auto "
    ml_half = "ml-half "
    ml1 = "ml1 "
    ml2 = "ml2 "
    ml3 = "ml3 "
    ml4 = "ml4 "
    ml5 = "ml5 "
    ml6 = "ml6 "
    mr0 = "mr0 "
    mr_auto = "mr-auto "
    mr_half = "mr-half "
    mr1 = "mr1 "
    mr2 = "mr2 "
    mr3 = "mr3 "
    mr4 = "mr4 "
    mr5 = "mr5 "
    mr6 = "mr6 "
    # Add other margins as needed


class Paddings:
    p0 = "p0 "
    p_half = "p-half "
    p1 = "p1 "
    p2 = "p2 "
    p3 = "p3 "
    p4 = "p4 "
    p5 = "p5 "
    p6 = "p6 "
    pt0 = "pt0 "
    pt_half = "pt-half "
    pt1 = "pt1 "
    pt2 = "pt2 "
    pt3 = "pt3 "
    pt4 = "pt4 "
    pt5 = "pt5 "
    pt6 = "pt6 "
    pb0 = "pb0 "
    pb_half = "pb-half "
    pb1 = "pb1 "
    pb2 = "pb2 "
    pb3 = "pb3 "
    pb4 = "pb4 "
    pb5 = "pb5 "
    pb6 = "pb6 "
    pl0 = "pl0 "
    pl_half = "pl-half "
    pl1 = "pl1 "
    pl2 = "pl2 "
    pl3 = "pl3 "
    pl4 = "pl4 "
    pl5 = "pl5 "
    pl6 = "pl6 "
    pr0 = "pr0 "
    pr_half = "pr-half "
    pr1 = "pr1 "
    pr2 = "pr2 "
    pr3 = "pr3 "
    pr4 = "pr4 "
    pr5 = "pr5 "
    pr6 = "pr6 "
    # Add other paddings as needed


class Visibility:
    d_none = "d-none "
    d_flex = "d-flex "
    d_block = "d-block "
    d_inline = "d-inline "
    d_inline_block = "d-inline-block "
    # Add other visibility classes as needed


class Opacity:
    transparent = "transparent "
    half_transparent = "half-transparent "
    opaque = "opaque "
    # Add other opacity classes as needed


class LayoutModifiers:
    # Layout block modifiers
    align_columns_top = "align-columns-top "
    align_columns_center = "align-columns-center "
    align_columns_bottom = "align-columns-bottom "
    align_columns_stretch = "align-columns-stretch "

    # Layout child part modifiers
    align_item_top = "align-item-top "
    align_item_center = "align-item-center "
    align_item_bottom = "align-item-bottom "
    align_item_stretch = "align-item-stretch "
    # Add other layout modifiers as needed


class Layout:
    taipy_layout = "taipy-layout"
    taipy_part = "taipy-part"
    taipy_dark = "taipy-dark"
    taipy_light = "taipy-light"
    # Add other layout classes as needed


class Theme:
    """Base Theme class."""

    def __init__(
        self,
        name,
        primary_color,
        secondary_color,
        border_radius,
        font_family,
        color_background_light,
        color_background_dark,
        color_paper_light,
        color_paper_dark,
        input_button_height,
    ):
        self.name = name
        self.primary_color = primary_color
        self.secondary_color = secondary_color
        self.border_radius = border_radius
        self.font_family = font_family
        self.color_background_light = color_background_light
        self.color_background_dark = color_background_dark
        self.color_paper_light = color_paper_light
        self.color_paper_dark = color_paper_dark
        self.input_button_height = input_button_height


class Themes:
    """Collection of themes for the Stylekit."""

    Default = Theme(
        name="Default",
        primary_color="#FF462B",
        secondary_color="#283282",
        border_radius=8,
        font_family="Lato, Arial, sans-serif",
        color_background_light="#F0F5F7",
        color_background_dark="#152335",
        color_paper_light="#FFFFFF",
        color_paper_dark="#1F2F44",
        input_button_height="48px",
    )

    #: Monospace Theme: Coding or terminal-like appearance.
    Monospace = Theme(
        name="Monospace",
        primary_color="#333333",
        secondary_color="#555555",
        border_radius="0px",
        font_family="'Courier New', monospace",
        color_background_light="#EFEFEF",
        color_background_dark="#2E2E2E",
        color_paper_light="#FFFFFF",
        color_paper_dark="#3C3C3C",
        input_button_height="44px",
    )

    #: Coffee Theme: Warm, cozy coffee shop atmosphere.
    Coffee = Theme(
        name="Coffee",
        primary_color="#6F4E37",
        secondary_color="#A67B5B",
        border_radius="12px",
        font_family="'Georgia', serif",
        color_background_light="#F5F5DC",
        color_background_dark="#4B3832",
        color_paper_light="#FFFFFF",
        color_paper_dark="#854442",
        input_button_height="50px",
    )

    #: Ocean Theme: Calm and refreshing aquatic feel.
    Ocean = Theme(
        name="Ocean",
        primary_color="#2E8BC0",
        secondary_color="#145DA0",
        border_radius="16px",
        font_family="'Arial', sans-serif",
        color_background_light="#B1D4E0",
        color_background_dark="#133B5C",
        color_paper_light="#FFFFFF",
        color_paper_dark="#1E5F74",
        input_button_height="48px",
    )

    #: Minimalist Theme: Clean and simple design.
    Minimalist = Theme(
        name="Minimalist",
        primary_color="#000000",
        secondary_color="#7F7F7F",
        border_radius="0px",
        font_family="'Helvetica Neue', sans-serif",
        color_background_light="#FFFFFF",
        color_background_dark="#F2F2F2",
        color_paper_light="#FFFFFF",
        color_paper_dark="#E6E6E6",
        input_button_height="46px",
    )

    #: Vibrant Theme: Playful and energetic appearance.
    Vibrant = Theme(
        name="Vibrant",
        primary_color="#FF6F61",
        secondary_color="#6B5B95",
        border_radius="24px",
        font_family="'Comic Sans MS', cursive, sans-serif",
        color_background_light="#FFF0E6",
        color_background_dark="#4A4A4A",
        color_paper_light="#FFFFFF",
        color_paper_dark="#FF6F61",
        input_button_height="52px",
    )

    #: Industrial Theme: Rugged and mechanical aesthetic.
    Industrial = Theme(
        name="Industrial",
        primary_color="#5A5A5A",
        secondary_color="#A1A1A1",
        border_radius="4px",
        font_family="'Roboto', sans-serif",
        color_background_light="#D3D3D3",
        color_background_dark="#2C2C2C",
        color_paper_light="#E0E0E0",
        color_paper_dark="#3A3A3A",
        input_button_height="48px",
    )

    #: Futuristic Theme: Sleek and modern design.
    Futuristic = Theme(
        name="Futuristic",
        primary_color="#00FFFF",
        secondary_color="#FF00FF",
        border_radius="20px",
        font_family="'Orbitron', sans-serif",
        color_background_light="#1A1A1A",
        color_background_dark="#000000",
        color_paper_light="#262626",
        color_paper_dark="#0D0D0D",
        input_button_height="50px",
    )

    #: Classic Theme: Traditional and timeless appearance.
    Classic = Theme(
        name="Classic",
        primary_color="#003366",
        secondary_color="#336699",
        border_radius="8px",
        font_family="'Times New Roman', serif",
        color_background_light="#CCCCCC",
        color_background_dark="#F0F0F0",
        color_paper_light="#CCCCCC",
        color_paper_dark="#E0E0E0",
        input_button_height="48px",
    )

    #: Nature Theme: Earthy and natural tones.
    Nature = Theme(
        name="Nature",
        primary_color="#6B8E23",
        secondary_color="#556B2F",
        border_radius="12px",
        font_family="'Verdana', sans-serif",
        color_background_light="#F5FFFA",
        color_background_dark="#2F4F4F",
        color_paper_light="#FFFFFF",
        color_paper_dark="#8FBC8F",
        input_button_height="48px",
    )

    #: HighContrast Theme: For accessibility and readability.
    HighContrast = Theme(
        name="HighContrast",
        primary_color="#FFFFFF",
        secondary_color="#000000",
        border_radius="0px",
        font_family="'Arial Black', sans-serif",
        color_background_light="#000000",
        color_background_dark="#000000",
        color_paper_light="#FFFFFF",
        color_paper_dark="#FFFFFF",
        input_button_height="48px",
    )


class Stylekit:
    components = Components()
    typography = Typography()
    text_weights = TextWeights()
    text_alignment = TextAlignment()
    margins = Margins()
    paddings = Paddings()
    visibility = Visibility()
    opacity = Opacity()
    layout = LayoutModifiers()
    themes = Themes()
    # Add other style properties as needed

    def __init__(self):
        # Default theme is 'Default'
        self.set_theme(self.themes.Default)

    def set_theme(self, theme):
        if isinstance(theme, Theme):
            self.stylekit = {
                "primary_color": theme.primary_color,
                "secondary_color": theme.secondary_color,
                "border_radius": theme.border_radius,
                "font_family": theme.font_family,
                "color_background_light": theme.color_background_light,
                "color_background_dark": theme.color_background_dark,
                "color_paper_light": theme.color_paper_light,
                "color_paper_dark": theme.color_paper_dark,
                "input_button_height": theme.input_button_height,
            }
        elif isinstance(theme, str):
            theme_obj = getattr(self.themes, theme, None)
            if theme_obj and isinstance(theme_obj, Theme):
                self.set_theme(theme_obj)
            else:
                available_themes = [
                    t
                    for t in dir(self.themes)
                    if not t.startswith("__")
                    and isinstance(getattr(self.themes, t), Theme)
                ]
                print(
                    f"Theme '{theme}' not recognized. Available themes: {', '.join(available_themes)}"
                )
        else:
            raise TypeError(
                "Theme must be a Theme instance or a string representing the theme name."
            )

    # You can add individual setter methods if needed
    def set_primary_color(self, color):
        self.stylekit["primary_color"] = color

    def set_secondary_color(self, color):
        self.stylekit["secondary_color"] = color

    def set_border_radius(self, radius):
        self.stylekit["border_radius"] = radius

    def set_font_family(self, family):
        self.stylekit["font_family"] = family

    def set_color_background_light(self, color):
        self.stylekit["color_background_light"] = color

    def set_color_background_dark(self, color):
        self.stylekit["color_background_dark"] = color

    def set_color_paper_light(self, color):
        self.stylekit["color_paper_light"] = color

    def set_color_paper_dark(self, color):
        self.stylekit["color_paper_dark"] = color

    def set_input_button_height(self, height):
        self.stylekit["input_button_height"] = height

    def get_stylekit(self):
        return self.stylekit


# Create an instance of Stylekit
stylekit = Stylekit()

@jrobinAV
Copy link
Member

jrobinAV commented Dec 30, 2024

Multiple issues relates to this one:

#1077
#2329
taipy-doc#1085

Set up a meeting to decide if we need to create more issues.

@jrobinAV
Copy link
Member

AFter discussion, it appears that the other issues are covering all the changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
💬 Discussion Open for discussion and feedback 📄 Documentation Internal or public documentation 🖰 GUI Related to GUI 📈 Improvement Improvement of a feature. 🟥 Priority: Critical Must be fixed ASAP
Projects
None yet
Development

No branches or pull requests

3 participants