首页 > 解决方案 > Shopify Polaris - 自定义布局问题和样式

问题描述

目前我正在尝试创建一个非常基本的废弃购物车应用程序,只是为了教自己更多关于 GraphQL 和 Shopify 使用 Polaris 创建应用程序的知识。Polaris 有很多组件,但我无法按照我的需要编辑它们。到目前为止,我还没有找到任何方法来改变组件或布局的样式,所以遇到了一些麻烦。我对编程并不陌生,但我对反应有些陌生。

我看到 Polaris 不支持样式,因为开发人员希望它在所有应用程序中保持一致。附上我有一些图片 - 我只是想知道我是否可以从当前移动到目标?

目标是在一列中放置三张卡片,它们下方有一个相同宽度的表格,并带有一个这样的空间。在这张图片中,桌子并没有完全穿过,但那是由于我制作这张图片的方式。

目前,它看起来像这样(多行状态) - 组件之间没有空间,尽管从组件库复制代码,三个相等的列跨越多行,而不是在同一行的第二个当前图像中,但是它要求中间卡必须不同(我认为如果它们是相同的内容它不会这样做)。卡和表下方也没有间隙——单线当前状态

我试图在其他地方在线查找并做一些解决方法,但我没有想法。由于北极星的限制,是否可以编辑卡片的当前状态以使其与目标状态相似?

[编辑] 为最后两张图片上传了相同的图片,已修复

[编辑 2] 添加代码 +图片

import { Checkbox , FormLayout , TextField , DataTable, ResourceList, DisplayText, EmptyState, Layout, Page , Card, TextStyle, Heading} from '@shopify/polaris';
import { ResourcePicker } from '@shopify/app-bridge-react';
import store from 'store-js';
import ResourceListWithProducts from '../components/ResourceList';


const img = 'https://cdn.shopify.com/s/files/1/0757/9955/files/empty-state.svg';

function SortableDataTableExample() {
  const [sortedRows, setSortedRows] = useState(null);

  const initiallySortedRows = [
    ['Emerald Silk Gown', '$875.00', 124689, 140, '$122,500.00'],
    ['Mauve Cashmere Scarf', '$230.00', 124533, 83, '$19,090.00'],
    [
      'Navy Merinaaso Wool Blazer with khaki chinos and yellow belt',
      '$445.00',
      124518,
      32,
      '$14,240.00',
    ],
  ];
  

  return (
    <Page title="Sales by product">
      <Card>
        <DataTable
          columnContentTypes={[
            'text',
            'numeric',
            'numeric',
            'numeric',
            'numeric',
          ]}
          headings={[
            'Product',
            'Price',
            'SKU Number',
            'Net quantity',
            'Net sales',
          ]}
          rows={rows}
          totals={['', '', '', 255, '$155,830.00']}
          sortable={[false, true, false, false, true]}
          defaultSortDirection="descending"
          initialSortColumnIndex={4}
          onSort={handleSort}
        />
      </Card>
    </Page>
  );

  
  function sortCurrency(rows, index, direction) {
    return [...rows].sort((rowA, rowB) => {
      const amountA = parseFloat(rowA[index].substring(1));
      const amountB = parseFloat(rowB[index].substring(1));

      return direction === 'descending' ? amountB - amountA : amountA - amountB;
    });
  }
}

class Index extends React.Component {
  state = { open: false };
  render() {

    

    const rows = [
      ['Abandon Cart (1 hr)', '74', 19, 1432, , 'true',],
      ['Abandon Cart (24 hrs)', '52', 23, 2132, , 'true'],,
      
    ];

    const emptyState = !store.get('ids');
    return (
      <Page
        primaryAction={{
          content: 'Select products',
          onAction: () => this.setState({ open: true }),
        }}
      >

        <ResourcePicker
          resourceType="Product"
          showVariants={false}
          open={this.state.open}
          onSelection={(resources) => this.handleSelection(resources)}
          onCancel={() => this.setState({ open: false })}
        />
        {emptyState ? (
          <Layout>

<Layout>
        <Layout.Section oneThird>
          <Card title="Emails Sent" actions={[{ content: "Manage" }]}>
            <Card.Section>
              <DisplayText size="large">172</DisplayText>
            </Card.Section>
          </Card>
        </Layout.Section>
        <Layout.Section oneThird>
          <Card title="Sales" actions={[{ content: "Manage" }]}>
            <Card.Section>
            <Layout>
        
        
        <Layout.Section oneThird>
          
        </Layout.Section>
      </Layout>
            </Card.Section>
          </Card>
        </Layout.Section>
        <Layout.Section oneThird>
          <Card title="ROI" actions={[{ content: "Manage" }]}>
            <Card.Section>
              <DisplayText size="large">+745%</DisplayText>
            </Card.Section>
          </Card>
        </Layout.Section>
      </Layout>

      <Card>
        <DataTable
          columnContentTypes={[
            'text',
            'numeric',
            'numeric',
            'numeric',
            'boolean',
          ]}
          headings={[
            'Email',
            'Emails Sent',
            'Orders',
            'Sales ($)',
            'Active',
            
          ]}
          rows={rows}
          totals={['', '', '', 3564, '']}
        />
      </Card>
     

            <EmptyState
              heading="Discount your products temporarily"
              action={{
                content: 'Select products',
                onAction: () => this.setState({ open: true }),
              }}
              image={img}
            >
              <p>Select products to change their price temporarily.</p>
            </EmptyState>
          </Layout>
        ) : (
            <ResourceListWithProducts />
          )}

          <FormLayout>
            <TextField type="text" label="Call Script" onChange={() => {}} />
            <TextField type="text" label="Voicemail Script" onChange={() => {}} />
          </FormLayout>


      </Page>
    );
  }

  handleSelection = (resources) => {
    const idsFromResources = resources.selection.map((product) => product.id);
    this.setState({ open: false });
    store.set('ids', idsFromResources);
  };
}

export default Index;`

标签: reactjsreact-nativeshopifyshopify-apppolaris

解决方案


您已经嵌套<Layout><Layout>导致列堆叠在一起。将其替换为包装<div>标签。对于底部的间距,我将三张卡片包裹在一个<div>标签中,并添加了paddingBottom: '15px'. 让我知道这是否是您想要的。

import { Checkbox , FormLayout , TextField , DataTable, ResourceList, DisplayText, EmptyState, Layout, Page , Card, TextStyle, Heading} from '@shopify/polaris';
import { ResourcePicker } from '@shopify/app-bridge-react';
import store from 'store-js';
import ResourceListWithProducts from '../components/ResourceList';


const img = 'https://cdn.shopify.com/s/files/1/0757/9955/files/empty-state.svg';

function SortableDataTableExample() {
  const [sortedRows, setSortedRows] = useState(null);

  const initiallySortedRows = [
    ['Emerald Silk Gown', '$875.00', 124689, 140, '$122,500.00'],
    ['Mauve Cashmere Scarf', '$230.00', 124533, 83, '$19,090.00'],
    [
      'Navy Merinaaso Wool Blazer with khaki chinos and yellow belt',
      '$445.00',
      124518,
      32,
      '$14,240.00',
    ],
  ];


  return (
    <Page title="Sales by product">
      <Card>
        <DataTable
          columnContentTypes={[
            'text',
            'numeric',
            'numeric',
            'numeric',
            'numeric',
          ]}
          headings={[
            'Product',
            'Price',
            'SKU Number',
            'Net quantity',
            'Net sales',
          ]}
          rows={rows}
          totals={['', '', '', 255, '$155,830.00']}
          sortable={[false, true, false, false, true]}
          defaultSortDirection="descending"
          initialSortColumnIndex={4}
          onSort={handleSort}
        />
      </Card>
    </Page>
  );


  function sortCurrency(rows, index, direction) {
    return [...rows].sort((rowA, rowB) => {
      const amountA = parseFloat(rowA[index].substring(1));
      const amountB = parseFloat(rowB[index].substring(1));

      return direction === 'descending' ? amountB - amountA : amountA - amountB;
    });
  }
}

class Index extends React.Component {
  state = { open: false };
  render() {



    const rows = [
      ['Abandon Cart (1 hr)', '74', 19, 1432, , 'true',],
      ['Abandon Cart (24 hrs)', '52', 23, 2132, , 'true'],,

    ];

    const emptyState = !store.get('ids');
    return (
      <Page
        primaryAction={{
          content: 'Select products',
          onAction: () => this.setState({ open: true }),
        }}
      >

        <ResourcePicker
          resourceType="Product"
          showVariants={false}
          open={this.state.open}
          onSelection={(resources) => this.handleSelection(resources)}
          onCancel={() => this.setState({ open: false })}
        />
        {emptyState ? (
          <div>

            <div style={{ paddingBottom : '15px' }}>
              <Layout>
                <Layout.Section oneThird>
                  <Card title="Emails Sent" actions={[{ content: "Manage" }]}>
                    <Card.Section>
                      <DisplayText size="large">172</DisplayText>
                    </Card.Section>
                  </Card>
                </Layout.Section>
                <Layout.Section oneThird>
                  <Card title="Sales" actions={[{ content: "Manage" }]}>
                    <Card.Section>
                      <DisplayText size="large">+$300</DisplayText>
                    </Card.Section>
                  </Card>
                </Layout.Section>
                <Layout.Section oneThird>
                  <Card title="ROI" actions={[{ content: "Manage" }]}>
                    <Card.Section>
                      <DisplayText size="large">+745%</DisplayText>
                    </Card.Section>
                  </Card>
                </Layout.Section>
              </Layout>
            </div>

            <Card>
              <DataTable
                columnContentTypes={[
                  'text',
                  'numeric',
                  'numeric',
                  'numeric',
                  'boolean',
                ]}
                headings={[
                  'Email',
                  'Emails Sent',
                  'Orders',
                  'Sales ($)',
                  'Active',

                ]}
                rows={rows}
                totals={['', '', '', 3564, '']}
              />
            </Card>


            <EmptyState
              heading="Discount your products temporarily"
              action={{
                content: 'Select products',
                onAction: () => this.setState({ open: true }),
              }}
              image={img}
            >
              <p>Select products to change their price temporarily.</p>
            </EmptyState>
          </div>
        ) : (
          <ResourceListWithProducts />
        )}

        <FormLayout>
          <TextField type="text" label="Call Script" onChange={() => {}} />
          <TextField type="text" label="Voicemail Script" onChange={() => {}} />
        </FormLayout>


      </Page>
    );
  }

  handleSelection = (resources) => {
    const idsFromResources = resources.selection.map((product) => product.id);
    this.setState({ open: false });
    store.set('ids', idsFromResources);
  };
}

export default Index;

推荐阅读