首页 web前端 css教程 如何用情感制作列表组成部分

如何用情感制作列表组成部分

Apr 04, 2025 am 09:29 AM

How to Make a List Component with Emotion

本周在 Sentry 进行代码重构时,我发现我们缺少一个可在项目和功能之间通用的通用列表组件。因此,我开始着手创建一个,但问题在于:我们在 Sentry 中使用 Emotion 进行样式设置,而我对 Emotion 只有初步的了解,其文档中对其描述为……

……一个用于使用 JavaScript 编写 CSS 样式的库。除了提供强大的、可预测的样式组合之外,它还提供出色的开发人员体验,其功能包括源映射、标签和测试实用程序。同时支持字符串和对象样式。

如果您从未听说过 Emotion,其基本思想如下:当我们在具有许多组件的大型代码库上工作时,我们希望确保可以控制 CSS 的层叠样式表。因此,假设您在一个文件中有一个 .active 类,并且您希望确保它不会影响另一个文件中也具有 .active 类的完全独立组件的样式。

Emotion 通过向您的类名添加自定义字符串来解决此问题,这样它们就不会与其他组件冲突。以下是它可能输出的 HTML 示例:

<div></div>
登录后复制

很简洁,对吧?但是,还有许多其他工具和工作流程可以实现非常类似的功能,例如 CSS Modules。

要开始创建组件,我们首先需要将 Emotion 安装到我们的项目中。我不会详细介绍这些内容,因为这取决于您的环境和设置。但是,一旦完成,我们就可以像这样创建一个新组件:

import React from 'react';
import styled from '@emotion/styled';

export const List = styled('ul')`
  list-style: none;
  padding: 0;
`;
登录后复制

这对我来说看起来很奇怪,因为我们不仅正在为 <ul></ul> 元素编写样式,而且还定义了组件也应该呈现一个 <ul></ul> 元素。在一个地方同时组合标记和样式感觉很奇怪,但我确实喜欢它的简单性。它只是有点扰乱了我的思维模型以及 HTML、CSS 和 JavaScript 之间的关注点分离。在另一个组件中,我们可以导入这个 <list></list> 并像这样使用它:

import List from 'components/list';

<list>这是一个列表项。</list>
登录后复制

然后,我们添加到列表组件中的样式将转换为类名(例如 .oefioaueg),然后添加到我们在组件中定义的 <ul></ul> 元素中。但我们还没有完成!对于列表设计,我需要能够使用相同的组件呈现 <ul></ul><ol&gt;</ol&gt;。我还需要一个允许我在每个列表项中放置图标的版本。就像这样:Emotion 的酷(而且有点奇怪)之处在于,我们可以使用 as 属性来选择导入组件时要呈现的 HTML 元素。我们可以使用此属性来创建我们的 <ol&gt;</ol&gt; 变体,而无需创建自定义类型属性或其他内容。而这看起来就像这样:

<list>这将呈现一个 ul。</list>
<list as="ol&quot;>这将呈现一个 ol。</list>
登录后复制

这不仅对我来说很奇怪,对吧?但是,这非常巧妙,因为这意味着我们不必在组件本身中进行任何奇怪的逻辑来更改标记。

这时,我开始记下这个组件的理想 API 可能是什么样子,因为然后我们可以从那里倒退回来。这就是我的设想:

<list>
  <listitem>项目 1</listitem>
  <listitem>项目 2</listitem>
  <listitem>项目 3</listitem>
</list>
<list>
  <listitem color="orange400" icon="{<IconBusiness" size="sm"></listitem>}>项目 1
  <listitem color="orange400" icon="{<IconBusiness" size="sm"></listitem>}>项目 2
  <listitem color="orange400" icon="{<IconBusiness" size="sm"></listitem>}>项目 3
</list>
<list as="ol&quot;>
  <listitem>项目 1</listitem>
  <listitem>项目 2</listitem>
  <listitem>项目 3</listitem>
</list>
登录后复制

因此,在制作此草图后,我知道我们需要两个组件,以及能够在 <listitem></listitem> 中嵌套图标子组件的能力。我们可以像这样开始:

import React from 'react';
import styled from '@emotion/styled';

export const List = styled('ul')`
  list-style: none;
  padding: 0;
  margin-bottom: 20px;

  ol&amp; {
    counter-reset: numberedList;
  }
`;
登录后复制

这种特殊的 ol& 语法是我们告诉 Emotion 这些样式仅在元素呈现为 <ol&gt;</ol&gt; 时才适用的方式。通常最好在此元素中添加 background: red; 以确保您的组件正确呈现内容。接下来是我们的子组件 <listitem></listitem>。需要注意的是,在 Sentry 中我们也使用 TypeScript,因此在定义我们的 <listitem></listitem> 组件之前,我们需要先设置我们的 props:

type ListItemProps = {
  icon?: React.ReactNode;
  children?: string | React.ReactNode;
  className?: string;
};
登录后复制

现在我们可以添加我们的 <iconwrapper></iconwrapper> 组件,它将在 <listitem></listitem> 中调整 <icon></icon> 组件的大小。如果您还记得上面的示例,我希望它看起来像这样:

<list>
  <listitem color="orange400" icon="{<IconBusiness" size="sm"></listitem>}>项目 1
  <listitem color="orange400" icon="{<IconBusiness" size="sm"></listitem>}>项目 2
  <listitem color="orange400" icon="{<IconBusiness" size="sm"></listitem>}>项目 3
</list>
登录后复制

IconBusiness 组件是一个预先存在的组件,我们希望将其包装在 <span></span> 中,以便我们可以对其进行样式设置。值得庆幸的是,我们只需要一点 CSS 就可以将图标与文本正确对齐,而 <iconwrapper></iconwrapper> 可以为我们处理所有这些:

type ListItemProps = {
  icon?: React.ReactNode;
  children?: string | React.ReactNode;
  className?: string;
};

const IconWrapper = styled('span')`
  display: flex;
  margin-right: 15px;
  height: 16px;
  align-items: center;
`;
登录后复制

完成此操作后,我们终于可以在这两个组件下方添加我们的 <listitem></listitem> 组件,尽管它要复杂得多。我们需要添加 props,然后当存在 icon prop 时,我们可以渲染上面的 <iconwrapper></iconwrapper>,并渲染传入其中的 icon 组件。我还添加了下面的所有样式,以便您可以看到我如何为这些变体中的每一个设置样式:

export const ListItem = styled(({ icon, className, children }: ListItemProps) => (
  
登录后复制
  • {icon && ({icon})} {children}
  • ))` display: flex; align-items: center; position: relative; padding-left: 34px; margin-bottom: 20px; /* Tiny circle and icon positioning */ &:before, > ${IconWrapper} { position: absolute; left: 0; } ul & { color: #aaa; /* This pseudo is the tiny circle for ul items */ &:before { content: ''; width: 6px; height: 6px; border-radius: 50%; margin-right: 15px; border: 1px solid #aaa; background-color: transparent; left: 5px; top: 10px; } /* Icon styles */ ${p => p.icon && ` span { top: 4px; } /* Removes tiny circle pseudo if icon is present */ &:before { content: none; } `} } /* When the list is rendered as an
      */ ol & { &:before { counter-increment: numberedList; content: counter(numberedList); top: 3px; display: flex; align-items: center; justify-content: center; text-align: center; width: 18px; height: 18px; font-size: 10px; font-weight: 600; border: 1px solid #aaa; border-radius: 50%; background-color: transparent; margin-right: 20px; } } `;

      就是这样!一个使用 Emotion 构建的相对简单的 <list></list> 组件。但是,在完成此练习后,我仍然不确定是否喜欢这种语法。我认为它让简单的事情变得 非常 简单,但中等大小的组件比应该的要 复杂 得多。此外,对于新手来说,它可能会非常令人困惑,这让我有点担心。

      但我想一切都是学习经验。无论如何,我很高兴有机会处理这个小型组件,因为它教会了我一些关于 TypeScript、React 以及如何使我们的样式在某种程度上可读的知识。

    以上是如何用情感制作列表组成部分的详细内容。更多信息请关注PHP中文网其他相关文章!

    本站声明
    本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

    热AI工具

    Undresser.AI Undress

    Undresser.AI Undress

    人工智能驱动的应用程序,用于创建逼真的裸体照片

    AI Clothes Remover

    AI Clothes Remover

    用于从照片中去除衣服的在线人工智能工具。

    Undress AI Tool

    Undress AI Tool

    免费脱衣服图片

    Clothoff.io

    Clothoff.io

    AI脱衣机

    Video Face Swap

    Video Face Swap

    使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

    热工具

    记事本++7.3.1

    记事本++7.3.1

    好用且免费的代码编辑器

    SublimeText3汉化版

    SublimeText3汉化版

    中文版,非常好用

    禅工作室 13.0.1

    禅工作室 13.0.1

    功能强大的PHP集成开发环境

    Dreamweaver CS6

    Dreamweaver CS6

    视觉化网页开发工具

    SublimeText3 Mac版

    SublimeText3 Mac版

    神级代码编辑软件(SublimeText3)

    热门话题

    Java教程
    1657
    14
    CakePHP 教程
    1415
    52
    Laravel 教程
    1309
    25
    PHP教程
    1257
    29
    C# 教程
    1229
    24
    Google字体可变字体 Google字体可变字体 Apr 09, 2025 am 10:42 AM

    我看到Google字体推出了新设计(Tweet)。与上一次大型重新设计相比,这感觉更加迭代。我几乎无法分辨出区别

    如何使用HTML,CSS和JavaScript创建动画倒计时计时器 如何使用HTML,CSS和JavaScript创建动画倒计时计时器 Apr 11, 2025 am 11:29 AM

    您是否曾经在项目上需要一个倒计时计时器?对于这样的东西,可以自然访问插件,但实际上更多

    HTML数据属性指南 HTML数据属性指南 Apr 11, 2025 am 11:50 AM

    您想了解的有关HTML,CSS和JavaScript中数据属性的所有信息。

    为什么Flex布局中的紫色斜线区域会被误认为是'溢出空间”? 为什么Flex布局中的紫色斜线区域会被误认为是'溢出空间”? Apr 05, 2025 pm 05:51 PM

    关于Flex布局中紫色斜线区域的疑问在使用Flex布局时,你可能会遇到一些令人困惑的现象,比如在开发者工具(d...

    如何通过CSS选择第一个类名为item的子元素? 如何通过CSS选择第一个类名为item的子元素? Apr 05, 2025 pm 11:24 PM

    在元素个数不固定的情况下如何通过CSS选择第一个指定类名的子元素在处理HTML结构时,常常会遇到元素个数不�...

    我们如何创建一个在SVG中生成格子呢模式的静态站点 我们如何创建一个在SVG中生成格子呢模式的静态站点 Apr 09, 2025 am 11:29 AM

    格子呢是一块图案布,通常与苏格兰有关,尤其是他们时尚的苏格兰语。在Tar​​tanify.com上,我们收集了5,000多个格子呢

    使Sass更快的概念证明 使Sass更快的概念证明 Apr 16, 2025 am 10:38 AM

    在一个新项目开始时,Sass汇编发生在眼睛的眨眼中。感觉很棒,尤其是当它与browsersync配对时,它重新加载

    为什么在Safari中自定义样式表能在本地网页生效,但在百度页面上却无法生效? 为什么在Safari中自定义样式表能在本地网页生效,但在百度页面上却无法生效? Apr 05, 2025 pm 05:15 PM

    在Safari中使用自定义样式表的问题探讨今天我们来探讨一个关于Safari浏览器的自定义样式表应用问题。前端新手...

    See all articles