This is an automated email from the ASF dual-hosted git repository.

beto pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 06945cc  feat: Icon Button (#14818)
06945cc is described below

commit 06945ccbcf4e7e7fe901c5e7a4ad83c8a629b59b
Author: Lyndsi Kay Williams <[email protected]>
AuthorDate: Tue Jun 1 22:47:42 2021 -0500

    feat: Icon Button (#14818)
    
    * Creating IconButton
    
    * Changed naming: logo is now icon
    
    * Hard-coded inset values for ellipses
    
    * Removed default SVG
    
    * Fixed test
    
    * Removed logo from test
---
 .../components/IconButton/IconButton.stories.tsx   |  58 ++++++++++
 .../src/components/IconButton/IconButton.test.jsx  |  38 +++++++
 .../src/components/IconButton/index.tsx            | 123 +++++++++++++++++++++
 3 files changed, 219 insertions(+)

diff --git a/superset-frontend/src/components/IconButton/IconButton.stories.tsx 
b/superset-frontend/src/components/IconButton/IconButton.stories.tsx
new file mode 100644
index 0000000..45435e7
--- /dev/null
+++ b/superset-frontend/src/components/IconButton/IconButton.stories.tsx
@@ -0,0 +1,58 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import React from 'react';
+import IconButton, { IconButtonProps } from '.';
+
+export default {
+  title: 'IconButton',
+  component: IconButton,
+};
+
+export const InteractiveIconButton = (args: IconButtonProps) => (
+  <IconButton
+    buttonText={args.buttonText}
+    altText={args.altText}
+    icon={args.icon}
+    href={args.href}
+    target={args.target}
+    htmlType={args.htmlType}
+  />
+);
+
+InteractiveIconButton.args = {
+  buttonText: 'This is the IconButton text',
+  altText: 'This is an example of non-default alt text',
+  href: 'https://preset.io/',
+  target: '_blank',
+};
+
+InteractiveIconButton.argTypes = {
+  icon: {
+    defaultValue: '/images/icons/sql.svg',
+    control: {
+      type: 'select',
+      options: [
+        '/images/icons/sql.svg',
+        '/images/icons/server.svg',
+        '/images/icons/image.svg',
+        'Click to see example alt text',
+      ],
+    },
+  },
+};
diff --git a/superset-frontend/src/components/IconButton/IconButton.test.jsx 
b/superset-frontend/src/components/IconButton/IconButton.test.jsx
new file mode 100644
index 0000000..4049001
--- /dev/null
+++ b/superset-frontend/src/components/IconButton/IconButton.test.jsx
@@ -0,0 +1,38 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import React from 'react';
+import { render, screen } from 'spec/helpers/testing-library';
+import IconButton from 'src/components/IconButton';
+
+const defaultProps = {
+  buttonText: 'This is the IconButton text',
+  icon: '/images/icons/sql.svg',
+};
+
+describe('IconButton', () => {
+  it('renders an IconButton', () => {
+    render(<IconButton {...defaultProps} />);
+
+    const icon = screen.getByRole('img');
+    const buttonText = screen.getByText(/this is the iconbutton text/i);
+
+    expect(icon).toBeVisible();
+    expect(buttonText).toBeVisible();
+  });
+});
diff --git a/superset-frontend/src/components/IconButton/index.tsx 
b/superset-frontend/src/components/IconButton/index.tsx
new file mode 100644
index 0000000..e7f9c2d
--- /dev/null
+++ b/superset-frontend/src/components/IconButton/index.tsx
@@ -0,0 +1,123 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import React from 'react';
+import { styled } from '@superset-ui/core';
+import Button from 'src/components/Button';
+import { ButtonProps as AntdButtonProps } from 'antd/lib/button';
+
+export interface IconButtonProps extends AntdButtonProps {
+  buttonText: string;
+  icon: string;
+  altText?: string;
+}
+
+const StyledButton = styled(Button)`
+  height: auto;
+  display: flex;
+  flex-direction: column;
+  padding: 0;
+`;
+const StyledImage = styled.div`
+  margin: ${({ theme }) => theme.gridUnit * 8}px 0;
+  padding: ${({ theme }) => theme.gridUnit * 4}px;
+
+  &:first-of-type {
+    margin-right: 0;
+  }
+
+  img {
+    width: fit-content;
+
+    &:first-of-type {
+      margin-right: 0;
+    }
+  }
+`;
+
+const StyledInner = styled.div`
+  max-height: calc(1.5em * 2);
+  overflow: hidden;
+  padding-right: 1rem;
+  position: relative;
+  white-space: break-spaces;
+
+  &::before {
+    content: '...';
+    inset-block-end: 0; /* "bottom" */
+    inset-inline-end: 8px; /* "right" */
+    position: absolute;
+  }
+
+  &::after {
+    background-color: ${({ theme }) => theme.colors.grayscale.light4};
+    content: '';
+    height: 1rem;
+    inset-inline-end: 8px; /* "right" */
+    position: absolute;
+    top: 4px;
+    width: 1rem;
+  }
+`;
+
+const StyledBottom = styled.div`
+  padding: ${({ theme }) => theme.gridUnit * 6}px
+    ${({ theme }) => theme.gridUnit * 4}px;
+  border-radius: 0 0 ${({ theme }) => theme.borderRadius}px
+    ${({ theme }) => theme.borderRadius}px;
+  background-color: ${({ theme }) => theme.colors.grayscale.light4};
+  width: 100%;
+  line-height: 1.5em;
+  overflow: hidden;
+  white-space: no-wrap;
+  text-overflow: ellipsis;
+
+  &:first-of-type {
+    margin-right: 0;
+  }
+`;
+
+const IconButton = styled(
+  ({ icon, altText, buttonText, ...props }: IconButtonProps) => (
+    <StyledButton {...props}>
+      <StyledImage>
+        <img src={icon} alt={altText} />
+      </StyledImage>
+      <StyledBottom>
+        <StyledInner>{buttonText}</StyledInner>
+      </StyledBottom>
+    </StyledButton>
+  ),
+)`
+  text-transform: none;
+  background-color: ${({ theme }) => theme.colors.grayscale.light5};
+  font-weight: ${({ theme }) => theme.typography.weights.normal};
+  color: ${({ theme }) => theme.colors.grayscale.dark2};
+  border: 1px solid ${({ theme }) => theme.colors.grayscale.light2};
+  margin: 0;
+  width: 100%;
+
+  &:hover,
+  &:focus {
+    background-color: ${({ theme }) => theme.colors.grayscale.light5};
+    color: ${({ theme }) => theme.colors.grayscale.dark2};
+    border: 1px solid ${({ theme }) => theme.colors.grayscale.light2};
+  }
+`;
+
+export default IconButton;

Reply via email to